| ︙ | | | ︙ | |
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
};
/*
* These bits may be ORed together into the "flags" field of a TcpState
* structure.
*/
#define TCP_NONBLOCKING (1<<0) /* Socket with non-blocking I/O */
#define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */
#define SOCKET_EOF (1<<2) /* A zero read happened on the
* socket. */
#define SOCKET_PENDING (1<<3) /* A message has been sent for this
* socket */
#define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to
* process an async connect. This
* flag indicates that reentry is
* still pending */
#define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */
/*
* These bits may be ORed together into the "testFlags" field of a TcpState
* structure.
*/
#define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated. Do not
* automatically continue connection
* process */
/*
* The following structure is what is added to the Tcl event queue when a
* socket event occurs.
*/
typedef struct {
|
>
|
|
|
<
|
<
|
<
|
|
|
>
>
|
|
|
>
|
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
};
/*
* These bits may be ORed together into the "flags" field of a TcpState
* structure.
*/
enum TcpStateFlags {
TCP_NONBLOCKING = (1<<0), /* Socket with non-blocking I/O */
TCP_ASYNC_CONNECT = (1<<1), /* Async connect in progress. */
SOCKET_EOF = (1<<2), /* A zero read happened on the socket. */
SOCKET_PENDING = (1<<3), /* A message has been sent for this socket */
TCP_ASYNC_PENDING = (1<<4), /* TcpConnect was called to process an async
* connect. This flag indicates that reentry
* is still pending. */
TCP_ASYNC_FAILED = (1<<5) /* An async connect finally failed */
};
/*
* These bits may be ORed together into the "testFlags" field of a TcpState
* structure.
*/
enum TcpStateTestFlags {
TCP_ASYNC_TEST_MODE = (1<<0)/* Async testing activated. Do not
* automatically continue connection
* process */
};
/*
* The following structure is what is added to the Tcl event queue when a
* socket event occurs.
*/
typedef struct {
|
| ︙ | | | ︙ | |
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
static Tcl_ThreadDataKey dataKey;
static WNDCLASSW windowClass;
/*
* Static routines for this file:
*/
static int TcpConnect(Tcl_Interp *interp,
TcpState *state);
static void InitSockets(void);
static TcpState * NewSocketInfo(SOCKET socket);
static void SocketExitHandler(ClientData clientData);
static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
static int SocketsEnabled(void);
static void TcpAccept(TcpFdList *fds, SOCKET newSocket, address addr);
|
|
<
|
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
static Tcl_ThreadDataKey dataKey;
static WNDCLASSW windowClass;
/*
* Static routines for this file:
*/
static int TcpConnect(Tcl_Interp *interp, TcpState *state);
static void InitSockets(void);
static TcpState * NewSocketInfo(SOCKET socket);
static void SocketExitHandler(ClientData clientData);
static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
static int SocketsEnabled(void);
static void TcpAccept(TcpFdList *fds, SOCKET newSocket, address addr);
|
| ︙ | | | ︙ | |
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
* Simple wrapper round the SendMessage syscall.
*/
#define SendSelectMessage(tsdPtr, message, payload) \
SendMessageW((tsdPtr)->hwnd, SOCKET_SELECT, \
(WPARAM) (message), (LPARAM) (payload))
/*
* Address print debug functions
*/
#if 0
void
printaddrinfo(
|
>
>
>
>
>
|
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
|
* Simple wrapper round the SendMessage syscall.
*/
#define SendSelectMessage(tsdPtr, message, payload) \
SendMessageW((tsdPtr)->hwnd, SOCKET_SELECT, \
(WPARAM) (message), (LPARAM) (payload))
/*
* The name of a variable that may be changed to suppress reverse DNS lookups.
*/
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"
/*
* Address print debug functions
*/
#if 0
void
printaddrinfo(
|
| ︙ | | | ︙ | |
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
|
Tcl_Encoding *encodingPtr)
{
WCHAR wbuf[256];
DWORD length = sizeof(wbuf)/sizeof(WCHAR);
Tcl_DString ds;
Tcl_DStringInit(&ds);
if (GetComputerNameExW(ComputerNamePhysicalDnsFullyQualified, wbuf, &length) != 0) {
/*
* Convert string from native to UTF then change to lowercase.
*/
Tcl_UtfToLower(Tcl_WCharToUtfDString(wbuf, -1, &ds));
} else {
|
|
>
|
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
|
Tcl_Encoding *encodingPtr)
{
WCHAR wbuf[256];
DWORD length = sizeof(wbuf)/sizeof(WCHAR);
Tcl_DString ds;
Tcl_DStringInit(&ds);
if (GetComputerNameExW(ComputerNamePhysicalDnsFullyQualified, wbuf,
&length) != 0) {
/*
* Convert string from native to UTF then change to lowercase.
*/
Tcl_UtfToLower(Tcl_WCharToUtfDString(wbuf, -1, &ds));
} else {
|
| ︙ | | | ︙ | |
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
|
}
/*
* Single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or
* TCL_WRITABLE so this should never be called for a server socket.
*/
if ((flags & TCL_CLOSE_READ) && (shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
Tcl_WinConvertError((DWORD) WSAGetLastError());
readError = Tcl_GetErrno();
}
if ((flags & TCL_CLOSE_WRITE) && (shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) {
Tcl_WinConvertError((DWORD) WSAGetLastError());
writeError = Tcl_GetErrno();
}
return (readError != 0) ? readError : writeError;
}
/*
|
>
|
>
|
|
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
|
}
/*
* Single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or
* TCL_WRITABLE so this should never be called for a server socket.
*/
if ((flags & TCL_CLOSE_READ) &&
(shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
Tcl_WinConvertError((DWORD) WSAGetLastError());
readError = Tcl_GetErrno();
}
if ((flags & TCL_CLOSE_WRITE) &&
(shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) {
Tcl_WinConvertError((DWORD) WSAGetLastError());
writeError = Tcl_GetErrno();
}
return (readError != 0) ? readError : writeError;
}
/*
|
| ︙ | | | ︙ | |
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
|
* initialized by caller. */
{
TcpState *statePtr = (TcpState *)instanceData;
char host[NI_MAXHOST], port[NI_MAXSERV];
SOCKET sock;
size_t len = 0;
int reverseDNS = 0;
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"
/*
* 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.
*/
|
<
|
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
|
* initialized by caller. */
{
TcpState *statePtr = (TcpState *)instanceData;
char host[NI_MAXHOST], port[NI_MAXSERV];
SOCKET sock;
size_t len = 0;
int reverseDNS = 0;
/*
* 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.
*/
|
| ︙ | | | ︙ | |
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
|
/*
* Return error message.
*/
if (err) {
Tcl_WinConvertError(err);
Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()),
-1);
}
}
}
return TCL_OK;
}
if ((len > 1) && (optionName[1] == 'c') &&
|
|
<
|
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
|
/*
* Return error message.
*/
if (err) {
Tcl_WinConvertError(err);
Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1);
}
}
}
return TCL_OK;
}
if ((len > 1) && (optionName[1] == 'c') &&
|
| ︙ | | | ︙ | |
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
|
/*
* Invoke the accept callback function.
*/
if (statePtr->acceptProc != NULL) {
getnameinfo(&(addr.sa), len, host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST|NI_NUMERICSERV);
statePtr->acceptProc(statePtr->acceptProcData, newInfoPtr->channel,
host, atoi(port));
}
}
/*
*----------------------------------------------------------------------
*
* InitSockets --
|
|
|
|
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
|
/*
* Invoke the accept callback function.
*/
if (statePtr->acceptProc != NULL) {
getnameinfo(&(addr.sa), len, host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV);
statePtr->acceptProc(statePtr->acceptProcData, newInfoPtr->channel,
host, atoi(port));
}
}
/*
*----------------------------------------------------------------------
*
* InitSockets --
|
| ︙ | | | ︙ | |
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
|
* Populate new FD.
*/
fds->fd = socket;
fds->statePtr = statePtr;
fds->next = NULL;
}
/*
*----------------------------------------------------------------------
*
* NewSocketInfo --
*
* This function allocates and initializes a new TcpState structure.
*
|
|
<
|
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
|
* Populate new FD.
*/
fds->fd = socket;
fds->statePtr = statePtr;
fds->next = NULL;
}
/*
*----------------------------------------------------------------------
*
* NewSocketInfo --
*
* This function allocates and initializes a new TcpState structure.
*
|
| ︙ | | | ︙ | |
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
|
* Processes socket events off the system queue.
*
*----------------------------------------------------------------------
*/
static int
WaitForSocketEvent(
TcpState *statePtr, /* Information about this socket. */
int events, /* Events to look for. May be one of
* FD_READ or FD_WRITE.
*/
int *errorCodePtr) /* Where to store errors? */
{
int result = 1;
int oldMode;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
/*
|
|
|
<
|
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
|
* Processes socket events off the system queue.
*
*----------------------------------------------------------------------
*/
static int
WaitForSocketEvent(
TcpState *statePtr, /* Information about this socket. */
int events, /* Events to look for. May be one of
* FD_READ or FD_WRITE. */
int *errorCodePtr) /* Where to store errors? */
{
int result = 1;
int oldMode;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
/*
|
| ︙ | | | ︙ | |