1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/*
* tclWinSock.c --
*
* This file contains Windows-specific socket related code.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclWinSock.c,v 1.49 2005/11/03 00:17:31 patthoyts Exp $
*/
#include "tclWinInt.h"
/*
* Make sure to remove the redirection defines set in tclWinPort.h that is in
* use in other sections of the core, except for us.
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/*
* tclWinSock.c --
*
* This file contains Windows-specific socket related code.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclWinSock.c,v 1.50 2005/11/04 00:06:51 dkf Exp $
*/
#include "tclWinInt.h"
/*
* Make sure to remove the redirection defines set in tclWinPort.h that is in
* use in other sections of the core, except for us.
|
| ︙ | | | ︙ | |
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
NULL, /* close2proc. */
TcpBlockProc, /* Set socket into (non-)blocking mode. */
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc */
TcpThreadActionProc, /* thread action proc */
};
/*
*----------------------------------------------------------------------
*
* InitSockets --
*
* Initialize the socket module. Attempts to load the wsock32.dll library
|
<
|
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
NULL, /* close2proc. */
TcpBlockProc, /* Set socket into (non-)blocking mode. */
NULL, /* flush proc. */
NULL, /* handler proc. */
NULL, /* wide seek proc */
TcpThreadActionProc, /* thread action proc */
};
/*
*----------------------------------------------------------------------
*
* InitSockets --
*
* Initialize the socket module. Attempts to load the wsock32.dll library
|
| ︙ | | | ︙ | |
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
|
* Dynamically loads wsock32.dll, and registers a new window class and
* creates a window for use in asynchronous socket notification.
*
*----------------------------------------------------------------------
*/
static void
InitSockets()
{
DWORD id;
WSADATA wsaData;
DWORD err;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
TclThreadDataKeyGet(&dataKey);
|
|
|
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
* Dynamically loads wsock32.dll, and registers a new window class and
* creates a window for use in asynchronous socket notification.
*
*----------------------------------------------------------------------
*/
static void
InitSockets(void)
{
DWORD id;
WSADATA wsaData;
DWORD err;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
TclThreadDataKeyGet(&dataKey);
|
| ︙ | | | ︙ | |
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
|
* None.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
SocketsEnabled()
{
int enabled;
Tcl_MutexLock(&socketMutex);
enabled = (winSock.hModule != NULL);
Tcl_MutexUnlock(&socketMutex);
return enabled;
}
|
|
|
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
|
* None.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
SocketsEnabled(void)
{
int enabled;
Tcl_MutexLock(&socketMutex);
enabled = (winSock.hModule != NULL);
Tcl_MutexUnlock(&socketMutex);
return enabled;
}
|
| ︙ | | | ︙ | |
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
|
* None.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static void
SocketExitHandler(clientData)
ClientData clientData; /* Not used. */
{
Tcl_MutexLock(&socketMutex);
if (winSock.hModule) {
/*
* Make sure the socket event handling window is cleaned-up for, at
* most, this thread.
*/
|
|
|
|
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
|
* None.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static void
SocketExitHandler(
ClientData clientData) /* Not used. */
{
Tcl_MutexLock(&socketMutex);
if (winSock.hModule) {
/*
* Make sure the socket event handling window is cleaned-up for, at
* most, this thread.
*/
|
| ︙ | | | ︙ | |
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
|
* Delete the event source.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static void
SocketThreadExitHandler(clientData)
ClientData clientData; /* Not used. */
{
ThreadSpecificData *tsdPtr =
(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr != NULL && tsdPtr->socketThread != NULL) {
DWORD exitCode;
|
|
|
|
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
|
* Delete the event source.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static void
SocketThreadExitHandler(
ClientData clientData) /* Not used. */
{
ThreadSpecificData *tsdPtr =
(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr != NULL && tsdPtr->socketThread != NULL) {
DWORD exitCode;
|
| ︙ | | | ︙ | |
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
|
* message handling thread associated to the calling thread for the
* subsystem of the driver.
*
*----------------------------------------------------------------------
*/
int
TclpHasSockets(interp)
Tcl_Interp *interp;
{
Tcl_MutexLock(&socketMutex);
InitSockets();
Tcl_MutexUnlock(&socketMutex);
if (SocketsEnabled()) {
return TCL_OK;
|
|
|
|
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
|
* message handling thread associated to the calling thread for the
* subsystem of the driver.
*
*----------------------------------------------------------------------
*/
int
TclpHasSockets(
Tcl_Interp *interp)
{
Tcl_MutexLock(&socketMutex);
InitSockets();
Tcl_MutexUnlock(&socketMutex);
if (SocketsEnabled()) {
return TCL_OK;
|
| ︙ | | | ︙ | |
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
|
* Side effects:
* Adjusts the block time if needed.
*
*----------------------------------------------------------------------
*/
void
SocketSetupProc(data, flags)
ClientData data; /* Not used. */
int flags; /* Event flags as passed to Tcl_DoOneEvent. */
{
SocketInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
|
|
|
|
|
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
|
* Side effects:
* Adjusts the block time if needed.
*
*----------------------------------------------------------------------
*/
void
SocketSetupProc(
ClientData data, /* Not used. */
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
SocketInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
|
| ︙ | | | ︙ | |
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
|
* Side effects:
* May queue an event.
*
*----------------------------------------------------------------------
*/
static void
SocketCheckProc(data, flags)
ClientData data; /* Not used. */
int flags; /* Event flags as passed to Tcl_DoOneEvent. */
{
SocketInfo *infoPtr;
SocketEvent *evPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
|
|
|
|
|
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
|
* Side effects:
* May queue an event.
*
*----------------------------------------------------------------------
*/
static void
SocketCheckProc(
ClientData data, /* Not used. */
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
SocketInfo *infoPtr;
SocketEvent *evPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
|
| ︙ | | | ︙ | |
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
|
* Side effects:
* Whatever the channel callback functions do.
*
*----------------------------------------------------------------------
*/
static int
SocketEventProc(evPtr, flags)
Tcl_Event *evPtr; /* Event to service. */
int flags; /* Flags that indicate what events to handle,
* such as TCL_FILE_EVENTS. */
{
SocketInfo *infoPtr;
SocketEvent *eventPtr = (SocketEvent *) evPtr;
int mask = 0;
int events;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
|
|
|
|
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
|
* Side effects:
* Whatever the channel callback functions do.
*
*----------------------------------------------------------------------
*/
static int
SocketEventProc(
Tcl_Event *evPtr, /* Event to service. */
int flags) /* Flags that indicate what events to handle,
* such as TCL_FILE_EVENTS. */
{
SocketInfo *infoPtr;
SocketEvent *eventPtr = (SocketEvent *) evPtr;
int mask = 0;
int events;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
| ︙ | | | ︙ | |
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpBlockProc(instanceData, mode)
ClientData instanceData; /* The socket to block/un-block. */
int mode; /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
if (mode == TCL_MODE_NONBLOCKING) {
infoPtr->flags |= SOCKET_ASYNC;
} else {
|
|
|
|
|
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpBlockProc(
ClientData instanceData, /* The socket to block/un-block. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
if (mode == TCL_MODE_NONBLOCKING) {
infoPtr->flags |= SOCKET_ASYNC;
} else {
|
| ︙ | | | ︙ | |
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
|
* Closes the socket.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
TcpCloseProc(instanceData, interp)
ClientData instanceData; /* The socket to close. */
Tcl_Interp *interp; /* Unused. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
/* TIP #218 */
int errorCode = 0;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
|
|
|
|
|
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
|
* Closes the socket.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
TcpCloseProc(
ClientData instanceData, /* The socket to close. */
Tcl_Interp *interp) /* Unused. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
/* TIP #218 */
int errorCode = 0;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
|
| ︙ | | | ︙ | |
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
|
* Side effects:
* None, except for allocation of memory.
*
*----------------------------------------------------------------------
*/
static SocketInfo *
NewSocketInfo(socket)
SOCKET socket;
{
SocketInfo *infoPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
infoPtr = (SocketInfo *) ckalloc((unsigned) sizeof(SocketInfo));
infoPtr->channel = 0;
infoPtr->socket = socket;
|
|
|
|
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
|
* Side effects:
* None, except for allocation of memory.
*
*----------------------------------------------------------------------
*/
static SocketInfo *
NewSocketInfo(
SOCKET socket)
{
SocketInfo *infoPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
infoPtr = (SocketInfo *) ckalloc((unsigned) sizeof(SocketInfo));
infoPtr->channel = 0;
infoPtr->socket = socket;
|
| ︙ | | | ︙ | |
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
|
* Side effects:
* None, except for allocation of memory.
*
*----------------------------------------------------------------------
*/
static SocketInfo *
CreateSocket(interp, port, host, server, myaddr, myport, async)
Tcl_Interp *interp; /* For error reporting; can be NULL. */
int port; /* Port number to open. */
CONST char *host; /* Name of host on which to open port. */
int server; /* 1 if socket should be a server socket, else
* 0 for a client socket. */
CONST char *myaddr; /* Optional client-side address */
int myport; /* Optional client-side port */
int async; /* If nonzero, connect client socket
* asynchronously. */
{
u_long flag = 1; /* Indicates nonblocking mode. */
int asyncConnect = 0; /* Will be 1 if async connect is in
* progress. */
SOCKADDR_IN sockaddr; /* Socket address */
SOCKADDR_IN mysockaddr; /* Socket address for client */
|
|
|
|
|
|
|
|
|
|
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
|
* Side effects:
* None, except for allocation of memory.
*
*----------------------------------------------------------------------
*/
static SocketInfo *
CreateSocket(
Tcl_Interp *interp, /* For error reporting; can be NULL. */
int port, /* Port number to open. */
CONST char *host, /* Name of host on which to open port. */
int server, /* 1 if socket should be a server socket, else
* 0 for a client socket. */
CONST char *myaddr, /* Optional client-side address */
int myport, /* Optional client-side port */
int async) /* If nonzero, connect client socket
* asynchronously. */
{
u_long flag = 1; /* Indicates nonblocking mode. */
int asyncConnect = 0; /* Will be 1 if async connect is in
* progress. */
SOCKADDR_IN sockaddr; /* Socket address */
SOCKADDR_IN mysockaddr; /* Socket address for client */
|
| ︙ | | | ︙ | |
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
|
return infoPtr;
error:
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
if (interp != NULL) {
Tcl_AppendResult(interp, "couldn't open socket: ",
Tcl_PosixError(interp), (char *) NULL);
}
if (sock != INVALID_SOCKET) {
winSock.closesocket(sock);
}
return NULL;
}
|
|
|
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
|
return infoPtr;
error:
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
if (interp != NULL) {
Tcl_AppendResult(interp, "couldn't open socket: ",
Tcl_PosixError(interp), NULL);
}
if (sock != INVALID_SOCKET) {
winSock.closesocket(sock);
}
return NULL;
}
|
| ︙ | | | ︙ | |
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
|
* Side effects:
* Fills in the *sockaddrPtr structure.
*
*----------------------------------------------------------------------
*/
static int
CreateSocketAddress(sockaddrPtr, host, port)
LPSOCKADDR_IN sockaddrPtr; /* Socket address */
CONST char *host; /* Host. NULL implies INADDR_ANY */
int port; /* Port number */
{
struct hostent *hostent; /* Host database entry */
struct in_addr addr; /* For 64/32 bit madness */
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
|
|
|
|
|
|
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
|
* Side effects:
* Fills in the *sockaddrPtr structure.
*
*----------------------------------------------------------------------
*/
static int
CreateSocketAddress(
LPSOCKADDR_IN sockaddrPtr, /* Socket address */
CONST char *host, /* Host. NULL implies INADDR_ANY */
int port) /* Port number */
{
struct hostent *hostent; /* Host database entry */
struct in_addr addr; /* For 64/32 bit madness */
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
|
| ︙ | | | ︙ | |
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
|
* Side effects:
* Processes socket events off the system queue.
*
*----------------------------------------------------------------------
*/
static int
WaitForSocketEvent(infoPtr, events, errorCodePtr)
SocketInfo *infoPtr; /* Information about this socket. */
int events; /* Events to look for. */
int *errorCodePtr; /* Where to store errors? */
{
int result = 1;
int oldMode;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
TclThreadDataKeyGet(&dataKey);
/*
|
|
|
|
|
|
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
|
* Side effects:
* Processes socket events off the system queue.
*
*----------------------------------------------------------------------
*/
static int
WaitForSocketEvent(
SocketInfo *infoPtr, /* Information about this socket. */
int events, /* Events to look for. */
int *errorCodePtr) /* Where to store errors? */
{
int result = 1;
int oldMode;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
TclThreadDataKeyGet(&dataKey);
/*
|
| ︙ | | | ︙ | |
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
|
* Side effects:
* Opens a client socket and creates a new channel.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async)
Tcl_Interp *interp; /* For error reporting; can be NULL. */
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, should connect client socket
* asynchronously. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
|
|
|
|
|
|
|
|
|
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
|
* Side effects:
* Opens a client socket and creates a new channel.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_OpenTcpClient(
Tcl_Interp *interp, /* For error reporting; can be NULL. */
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, should connect client socket
* asynchronously. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
|
| ︙ | | | ︙ | |
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
|
*
* NOTE: Code contributed by Mark Diekhans (markd@grizzly.com)
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_MakeTcpClientChannel(sock)
ClientData sock; /* The socket to wrap up into a channel. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
ThreadSpecificData *tsdPtr;
if (TclpHasSockets(NULL) != TCL_OK) {
return NULL;
|
|
|
|
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
|
*
* NOTE: Code contributed by Mark Diekhans (markd@grizzly.com)
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_MakeTcpClientChannel(
ClientData sock) /* The socket to wrap up into a channel. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
ThreadSpecificData *tsdPtr;
if (TclpHasSockets(NULL) != TCL_OK) {
return NULL;
|
| ︙ | | | ︙ | |
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
|
* Side effects:
* Opens a server socket and creates a new channel.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_OpenTcpServer(interp, port, host, acceptProc, acceptProcData)
Tcl_Interp *interp; /* For error reporting - may be NULL. */
int port; /* Port number to open. */
CONST char *host; /* Name of local host. */
Tcl_TcpAcceptProc *acceptProc;
/* Callback for accepting connections from new
* clients. */
ClientData acceptProcData; /* Data for the callback. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
}
|
|
|
|
|
|
|
|
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
|
* Side effects:
* Opens a server socket and creates a new channel.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_OpenTcpServer(
Tcl_Interp *interp, /* For error reporting - may be NULL. */
int port, /* Port number to open. */
CONST char *host, /* Name of local host. */
Tcl_TcpAcceptProc *acceptProc,
/* Callback for accepting connections from new
* clients. */
ClientData acceptProcData) /* Data for the callback. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
}
|
| ︙ | | | ︙ | |
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
|
* Side effects:
* Invokes the accept proc which may invoke arbitrary Tcl code.
*
*----------------------------------------------------------------------
*/
static void
TcpAccept(infoPtr)
SocketInfo *infoPtr; /* Socket to accept. */
{
SOCKET newSocket;
SocketInfo *newInfoPtr;
SOCKADDR_IN addr;
int len;
char channelName[16 + TCL_INTEGER_SPACE];
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
|
|
|
|
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
|
* Side effects:
* Invokes the accept proc which may invoke arbitrary Tcl code.
*
*----------------------------------------------------------------------
*/
static void
TcpAccept(
SocketInfo *infoPtr) /* Socket to accept. */
{
SOCKET newSocket;
SocketInfo *newInfoPtr;
SOCKADDR_IN addr;
int len;
char channelName[16 + TCL_INTEGER_SPACE];
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
|
| ︙ | | | ︙ | |
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
|
* Side effects:
* Consumes input from the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpInputProc(instanceData, buf, toRead, errorCodePtr)
ClientData instanceData; /* The socket state. */
char *buf; /* Where to store data. */
int toRead; /* Maximum number of bytes to read. */
int *errorCodePtr; /* Where to store error codes. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int bytesRead;
DWORD error;
ThreadSpecificData *tsdPtr =
(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
|
|
|
|
|
|
|
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
|
* Side effects:
* Consumes input from the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpInputProc(
ClientData instanceData, /* The socket state. */
char *buf, /* Where to store data. */
int toRead, /* Maximum number of bytes to read. */
int *errorCodePtr) /* Where to store error codes. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int bytesRead;
DWORD error;
ThreadSpecificData *tsdPtr =
(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
|
| ︙ | | | ︙ | |
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
|
* Side effects:
* Produces output on the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpOutputProc(instanceData, buf, toWrite, errorCodePtr)
ClientData instanceData; /* The socket state. */
CONST char *buf; /* Where to get data. */
int toWrite; /* Maximum number of bytes to write. */
int *errorCodePtr; /* Where to store error codes. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int bytesWritten;
DWORD error;
ThreadSpecificData *tsdPtr =
(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
|
|
|
|
|
|
|
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
|
* Side effects:
* Produces output on the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpOutputProc(
ClientData instanceData, /* The socket state. */
CONST char *buf, /* Where to get data. */
int toWrite, /* Maximum number of bytes to write. */
int *errorCodePtr) /* Where to store error codes. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int bytesWritten;
DWORD error;
ThreadSpecificData *tsdPtr =
(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
|
| ︙ | | | ︙ | |
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
|
* Side effects:
* Changes attributes of the socket at the system level.
*
*----------------------------------------------------------------------
*/
static int
TcpSetOptionProc (
ClientData instanceData, /* Socket state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
CONST char *optionName, /* Name of the option to set. */
CONST char *value) /* New value for option. */
{
SocketInfo *infoPtr;
SOCKET sock;
|
|
|
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
|
* Side effects:
* Changes attributes of the socket at the system level.
*
*----------------------------------------------------------------------
*/
static int
TcpSetOptionProc(
ClientData instanceData, /* Socket state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
CONST char *optionName, /* Name of the option to set. */
CONST char *value) /* New value for option. */
{
SocketInfo *infoPtr;
SOCKET sock;
|
| ︙ | | | ︙ | |
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpGetOptionProc(instanceData, interp, optionName, dsPtr)
ClientData instanceData; /* Socket state. */
Tcl_Interp *interp; /* For error reporting - can be NULL */
CONST char *optionName; /* Name of the option to retrieve the value
* for, or NULL to get all options and their
* values. */
Tcl_DString *dsPtr; /* Where to store the computed value;
* initialized by caller. */
{
SocketInfo *infoPtr;
SOCKADDR_IN sockname;
SOCKADDR_IN peername;
struct hostent *hostEntPtr;
SOCKET sock;
|
|
|
|
|
|
|
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpGetOptionProc(
ClientData instanceData, /* Socket state. */
Tcl_Interp *interp, /* For error reporting - can be NULL */
CONST char *optionName, /* Name of the option to retrieve the value
* for, or NULL to get all options and their
* values. */
Tcl_DString *dsPtr) /* Where to store the computed value;
* initialized by caller. */
{
SocketInfo *infoPtr;
SOCKADDR_IN sockname;
SOCKADDR_IN peername;
struct hostent *hostEntPtr;
SOCKET sock;
|
| ︙ | | | ︙ | |
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
|
Tcl_AppendResult(interp, "winsock is not initialized", NULL);
}
return TCL_ERROR;
}
infoPtr = (SocketInfo *) instanceData;
sock = (int) infoPtr->socket;
if (optionName != (char *) NULL) {
len = strlen(optionName);
}
if ((len > 1) && (optionName[1] == 'e') &&
(strncmp(optionName, "-error", len) == 0)) {
int optlen;
DWORD err;
|
|
|
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
|
Tcl_AppendResult(interp, "winsock is not initialized", NULL);
}
return TCL_ERROR;
}
infoPtr = (SocketInfo *) instanceData;
sock = (int) infoPtr->socket;
if (optionName != NULL) {
len = strlen(optionName);
}
if ((len > 1) && (optionName[1] == 'e') &&
(strncmp(optionName, "-error", len) == 0)) {
int optlen;
DWORD err;
|
| ︙ | | | ︙ | |
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
|
Tcl_DStringAppendElement(dsPtr, "-peername");
Tcl_DStringStartSublist(dsPtr);
}
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(peername.sin_addr));
if (peername.sin_addr.s_addr == 0) {
hostEntPtr = (struct hostent *) NULL;
} else {
hostEntPtr = winSock.gethostbyaddr(
(char *) &(peername.sin_addr),
sizeof(peername.sin_addr), AF_INET);
}
if (hostEntPtr != (struct hostent *) NULL) {
Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
} else {
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(peername.sin_addr));
}
TclFormatInt(buf, winSock.ntohs(peername.sin_port));
Tcl_DStringAppendElement(dsPtr, buf);
|
|
|
|
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
|
Tcl_DStringAppendElement(dsPtr, "-peername");
Tcl_DStringStartSublist(dsPtr);
}
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(peername.sin_addr));
if (peername.sin_addr.s_addr == 0) {
hostEntPtr = NULL;
} else {
hostEntPtr = winSock.gethostbyaddr(
(char *) &(peername.sin_addr),
sizeof(peername.sin_addr), AF_INET);
}
if (hostEntPtr != NULL) {
Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
} else {
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(peername.sin_addr));
}
TclFormatInt(buf, winSock.ntohs(peername.sin_port));
Tcl_DStringAppendElement(dsPtr, buf);
|
| ︙ | | | ︙ | |
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
|
* {Copied from unix/tclUnixChan.c}
*/
if (len) {
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
if (interp) {
Tcl_AppendResult(interp, "can't get peername: ",
Tcl_PosixError(interp), (char *) NULL);
}
return TCL_ERROR;
}
}
}
if ((len == 0) || ((len > 1) && (optionName[1] == 's') &&
(strncmp(optionName, "-sockname", len) == 0))) {
if (winSock.getsockname(sock, (LPSOCKADDR) &sockname, &size) == 0) {
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-sockname");
Tcl_DStringStartSublist(dsPtr);
}
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(sockname.sin_addr));
if (sockname.sin_addr.s_addr == 0) {
hostEntPtr = (struct hostent *) NULL;
} else {
hostEntPtr = winSock.gethostbyaddr(
(char *) &(sockname.sin_addr),
sizeof(peername.sin_addr), AF_INET);
}
if (hostEntPtr != (struct hostent *) NULL) {
Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
} else {
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(sockname.sin_addr));
}
TclFormatInt(buf, winSock.ntohs(sockname.sin_port));
Tcl_DStringAppendElement(dsPtr, buf);
if (len == 0) {
Tcl_DStringEndSublist(dsPtr);
} else {
return TCL_OK;
}
} else {
if (interp) {
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
Tcl_AppendResult(interp, "can't get sockname: ",
Tcl_PosixError(interp), (char *) NULL);
}
return TCL_ERROR;
}
}
/*
if (len == 0 || !strncmp(optionName, "-keepalive", len)) {
|
|
|
|
|
|
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
|
* {Copied from unix/tclUnixChan.c}
*/
if (len) {
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
if (interp) {
Tcl_AppendResult(interp, "can't get peername: ",
Tcl_PosixError(interp), NULL);
}
return TCL_ERROR;
}
}
}
if ((len == 0) || ((len > 1) && (optionName[1] == 's') &&
(strncmp(optionName, "-sockname", len) == 0))) {
if (winSock.getsockname(sock, (LPSOCKADDR) &sockname, &size) == 0) {
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-sockname");
Tcl_DStringStartSublist(dsPtr);
}
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(sockname.sin_addr));
if (sockname.sin_addr.s_addr == 0) {
hostEntPtr = NULL;
} else {
hostEntPtr = winSock.gethostbyaddr(
(char *) &(sockname.sin_addr),
sizeof(peername.sin_addr), AF_INET);
}
if (hostEntPtr != NULL) {
Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
} else {
Tcl_DStringAppendElement(dsPtr,
winSock.inet_ntoa(sockname.sin_addr));
}
TclFormatInt(buf, winSock.ntohs(sockname.sin_port));
Tcl_DStringAppendElement(dsPtr, buf);
if (len == 0) {
Tcl_DStringEndSublist(dsPtr);
} else {
return TCL_OK;
}
} else {
if (interp) {
TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
Tcl_AppendResult(interp, "can't get sockname: ",
Tcl_PosixError(interp), NULL);
}
return TCL_ERROR;
}
}
/*
if (len == 0 || !strncmp(optionName, "-keepalive", len)) {
|
| ︙ | | | ︙ | |
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
|
* May cause the notifier to poll if any of the specified conditions are
* already true.
*
*----------------------------------------------------------------------
*/
static void
TcpWatchProc(instanceData, mask)
ClientData instanceData; /* The socket state. */
int mask; /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
/*
* Update the watch events mask. Only if the socket is not a server
|
|
|
|
|
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
|
* May cause the notifier to poll if any of the specified conditions are
* already true.
*
*----------------------------------------------------------------------
*/
static void
TcpWatchProc(
ClientData instanceData, /* The socket state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
/*
* Update the watch events mask. Only if the socket is not a server
|
| ︙ | | | ︙ | |
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpGetHandleProc(instanceData, direction, handlePtr)
ClientData instanceData; /* The socket state. */
int direction; /* Not used. */
ClientData *handlePtr; /* Where to store the handle. */
{
SocketInfo *statePtr = (SocketInfo *) instanceData;
*handlePtr = (ClientData) statePtr->socket;
return TCL_OK;
}
|
|
|
|
|
|
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpGetHandleProc(
ClientData instanceData, /* The socket state. */
int direction, /* Not used. */
ClientData *handlePtr) /* Where to store the handle. */
{
SocketInfo *statePtr = (SocketInfo *) instanceData;
*handlePtr = (ClientData) statePtr->socket;
return TCL_OK;
}
|
| ︙ | | | ︙ | |
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
SocketThread(LPVOID arg)
{
MSG msg;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)(arg);
tsdPtr->hwnd = CreateWindow("TclSocket", "TclSocket",
WS_TILED, 0, 0, 0, 0, NULL, NULL, windowClass.hInstance, arg);
|
|
>
|
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
|
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
SocketThread(
LPVOID arg)
{
MSG msg;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)(arg);
tsdPtr->hwnd = CreateWindow("TclSocket", "TclSocket",
WS_TILED, 0, 0, 0, 0, NULL, NULL, windowClass.hInstance, arg);
|
| ︙ | | | ︙ | |
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
|
* The flags for the given socket are updated to reflect the event that
* occured.
*
*----------------------------------------------------------------------
*/
static LRESULT CALLBACK
SocketProc(hwnd, message, wParam, lParam)
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
int event, error;
SOCKET socket;
SocketInfo *infoPtr;
ThreadSpecificData *tsdPtr =
#ifdef _WIN64
(ThreadSpecificData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
|
|
|
|
|
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
|
* The flags for the given socket are updated to reflect the event that
* occured.
*
*----------------------------------------------------------------------
*/
static LRESULT CALLBACK
SocketProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
int event, error;
SOCKET socket;
SocketInfo *infoPtr;
ThreadSpecificData *tsdPtr =
#ifdef _WIN64
(ThreadSpecificData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
| ︙ | | | ︙ | |
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
|
* Side effects:
* Caches the name to return for future calls.
*
*----------------------------------------------------------------------
*/
CONST char *
Tcl_GetHostName()
{
return Tcl_GetString(TclGetProcessGlobalValue(&hostName));
}
/*
*----------------------------------------------------------------------
*
* InitializeHostName --
*
* This routine sets the process global value of the name of the local
* host on which the process is running.
*
* Results:
* None.
*
*----------------------------------------------------------------------
*/
void
InitializeHostName(valuePtr, lengthPtr, encodingPtr)
char **valuePtr;
int *lengthPtr;
Tcl_Encoding *encodingPtr;
{
WCHAR wbuf[MAX_COMPUTERNAME_LENGTH + 1];
DWORD length = sizeof(wbuf) / sizeof(WCHAR);
Tcl_DString ds;
if ((*tclWinProcs->getComputerNameProc)(wbuf, &length) != 0) {
/*
|
|
|
|
|
|
|
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
|
* Side effects:
* Caches the name to return for future calls.
*
*----------------------------------------------------------------------
*/
CONST char *
Tcl_GetHostName(void)
{
return Tcl_GetString(TclGetProcessGlobalValue(&hostName));
}
/*
*----------------------------------------------------------------------
*
* InitializeHostName --
*
* This routine sets the process global value of the name of the local
* host on which the process is running.
*
* Results:
* None.
*
*----------------------------------------------------------------------
*/
void
InitializeHostName(
char **valuePtr,
int *lengthPtr,
Tcl_Encoding *encodingPtr)
{
WCHAR wbuf[MAX_COMPUTERNAME_LENGTH + 1];
DWORD length = sizeof(wbuf) / sizeof(WCHAR);
Tcl_DString ds;
if ((*tclWinProcs->getComputerNameProc)(wbuf, &length) != 0) {
/*
|
| ︙ | | | ︙ | |
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
|
* Side effects:
* As defined for each function.
*
*----------------------------------------------------------------------
*/
int
TclWinGetSockOpt(SOCKET s, int level, int optname, char * optval,
int FAR *optlen)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return SOCKET_ERROR;
}
return winSock.getsockopt(s, level, optname, optval, optlen);
}
int
TclWinSetSockOpt(SOCKET s, int level, int optname, const char * optval,
int optlen)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return SOCKET_ERROR;
}
return winSock.setsockopt(s, level, optname, optval, optlen);
}
u_short
TclWinNToHS(u_short netshort)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return (u_short) -1;
}
return winSock.ntohs(netshort);
}
struct servent *
TclWinGetServByName(const char * name, const char * proto)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return (struct servent *) NULL;
}
return winSock.getservbyname(name, proto);
}
/*
*----------------------------------------------------------------------
|
|
>
>
>
>
|
|
>
>
>
>
|
|
>
|
>
>
|
|
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
|
* Side effects:
* As defined for each function.
*
*----------------------------------------------------------------------
*/
int
TclWinGetSockOpt(
SOCKET s,
int level,
int optname,
char * optval,
int FAR *optlen)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return SOCKET_ERROR;
}
return winSock.getsockopt(s, level, optname, optval, optlen);
}
int
TclWinSetSockOpt(
SOCKET s,
int level,
int optname,
const char * optval,
int optlen)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return SOCKET_ERROR;
}
return winSock.setsockopt(s, level, optname, optval, optlen);
}
u_short
TclWinNToHS(
u_short netshort)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return (u_short) -1;
}
return winSock.ntohs(netshort);
}
struct servent *
TclWinGetServByName(
const char *name,
const char *proto)
{
/*
* Check that WinSock is initialized; do not call it if not, to prevent
* system crashes. This can happen at exit time if the exit handler for
* WinSock ran before other exit handlers that want to use sockets.
*/
if (!SocketsEnabled()) {
return NULL;
}
return winSock.getservbyname(name, proto);
}
/*
*----------------------------------------------------------------------
|
| ︙ | | | ︙ | |
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
|
* Side effects:
* Changes thread local list of valid channels.
*
*----------------------------------------------------------------------
*/
static void
TcpThreadActionProc (instanceData, action)
ClientData instanceData;
int action;
{
ThreadSpecificData *tsdPtr;
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int notifyCmd;
if (action == TCL_CHANNEL_THREAD_INSERT) {
/*
|
|
|
|
|
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
|
* Side effects:
* Changes thread local list of valid channels.
*
*----------------------------------------------------------------------
*/
static void
TcpThreadActionProc(
ClientData instanceData,
int action)
{
ThreadSpecificData *tsdPtr;
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int notifyCmd;
if (action == TCL_CHANNEL_THREAD_INSERT) {
/*
|
| ︙ | | | ︙ | |