Diff
Not logged in

Differences From Artifact [dc3f1cdd34]:

To Artifact [e035243747]:


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
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 {
#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
    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. */
#define SOCKET_PENDING		(1<<3)	/* A message has been sent for this
    SOCKET_PENDING = (1<<3),	/* A message has been sent for this socket */
					 * socket */
#define TCP_ASYNC_PENDING	(1<<4)	/* TcpConnect was called to
    TCP_ASYNC_PENDING = (1<<4),	/* TcpConnect was called to process an async
					 * process an async connect. This
					 * flag indicates that reentry is
					 * still pending */
#define TCP_ASYNC_FAILED	(1<<5)	/* An async connect finally failed */
                                 * 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 {
#define TCP_ASYNC_TEST_MODE	(1<<0)	/* Async testing activated.  Do not
					 * automatically continue connection
					 * process */
    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
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,
static int		TcpConnect(Tcl_Interp *interp, TcpState *state);
			    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
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
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) {
    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
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) &&
    if ((flags & TCL_CLOSE_READ) && (shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
            (shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
	Tcl_WinConvertError((DWORD) WSAGetLastError());
	readError = Tcl_GetErrno();
    }
    if ((flags & TCL_CLOSE_WRITE) &&
    if ((flags & TCL_CLOSE_WRITE) && (shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) {
            (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
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;
#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.
     */

1379
1380
1381
1382
1383
1384
1385
1386

1387
1388
1389
1390
1391
1392
1393
1394
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()),
		    Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1);
                            -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
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);
                NI_NUMERICHOST | NI_NUMERICSERV);
	statePtr->acceptProc(statePtr->acceptProcData, newInfoPtr->channel,
			    host, atoi(port));
		host, atoi(port));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * InitSockets --
3007
3008
3009
3010
3011
3012
3013
3014

3015
3016
3017
3018
3019
3020
3021
3022
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
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. */
    TcpState *statePtr,         /* Information about this socket. */
    int events,			/* Events to look for. May be one of
				 * FD_READ or FD_WRITE.
				 * FD_READ or FD_WRITE. */
				 */
    int *errorCodePtr)		/* Where to store errors? */
{
    int result = 1;
    int oldMode;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    /*