| ︙ | | | ︙ | |
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
|
if (ringPtr->capacity - ringPtr->start > ringPtr->length) {
/* There is room at the back */
RingSizeT endSpaceStart = ringPtr->start + ringPtr->length;
RingSizeT endSpace = ringPtr->capacity - endSpaceStart;
if (endSpace >= srcLen) {
/* Everything fits at the back */
memmove(endSpaceStart + ringPtr->bufPtr, srcPtr, srcLen);
}
else {
/* srcLen > endSpace */
memmove(endSpaceStart + ringPtr->bufPtr, srcPtr, endSpace);
memmove(ringPtr->bufPtr, endSpace + srcPtr, srcLen - endSpace);
}
}
else {
/* No room at the back. Existing data wrap to front. */
RingSizeT wrapLen =
ringPtr->start + ringPtr->length - ringPtr->capacity;
memmove(wrapLen + ringPtr->bufPtr, srcPtr, srcLen);
}
ringPtr->length += srcLen;
|
<
|
<
|
|
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
|
if (ringPtr->capacity - ringPtr->start > ringPtr->length) {
/* There is room at the back */
RingSizeT endSpaceStart = ringPtr->start + ringPtr->length;
RingSizeT endSpace = ringPtr->capacity - endSpaceStart;
if (endSpace >= srcLen) {
/* Everything fits at the back */
memmove(endSpaceStart + ringPtr->bufPtr, srcPtr, srcLen);
} else {
/* srcLen > endSpace */
memmove(endSpaceStart + ringPtr->bufPtr, srcPtr, endSpace);
memmove(ringPtr->bufPtr, endSpace + srcPtr, srcLen - endSpace);
}
} else {
/* No room at the back. Existing data wrap to front. */
RingSizeT wrapLen =
ringPtr->start + ringPtr->length - ringPtr->capacity;
memmove(wrapLen + ringPtr->bufPtr, srcPtr, srcLen);
}
ringPtr->length += srcLen;
|
| ︙ | | | ︙ | |
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
|
}
dstCapacity = ringPtr->length;
}
if (ringPtr->start <= (ringPtr->capacity - ringPtr->length)) {
/* No content wrap around. So leadLen is entire content */
leadLen = ringPtr->length;
}
else {
/* Content wraps around so lead segment stretches to end of buffer */
leadLen = ringPtr->capacity - ringPtr->start;
}
if (leadLen >= dstCapacity) {
if (dstPtr) {
memmove(dstPtr, ringPtr->start + ringPtr->bufPtr, dstCapacity);
}
ringPtr->start += dstCapacity;
}
else {
RingSizeT wrapLen = dstCapacity - leadLen;
if (dstPtr) {
memmove(dstPtr,
ringPtr->start + ringPtr->bufPtr,
leadLen);
memmove(
leadLen + dstPtr, ringPtr->bufPtr, wrapLen);
|
<
|
<
|
|
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
|
}
dstCapacity = ringPtr->length;
}
if (ringPtr->start <= (ringPtr->capacity - ringPtr->length)) {
/* No content wrap around. So leadLen is entire content */
leadLen = ringPtr->length;
} else {
/* Content wraps around so lead segment stretches to end of buffer */
leadLen = ringPtr->capacity - ringPtr->start;
}
if (leadLen >= dstCapacity) {
if (dstPtr) {
memmove(dstPtr, ringPtr->start + ringPtr->bufPtr, dstCapacity);
}
ringPtr->start += dstCapacity;
} else {
RingSizeT wrapLen = dstCapacity - leadLen;
if (dstPtr) {
memmove(dstPtr,
ringPtr->start + ringPtr->bufPtr,
leadLen);
memmove(
leadLen + dstPtr, ringPtr->bufPtr, wrapLen);
|
| ︙ | | | ︙ | |
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
|
if (result) {
if ((nRead == 0 || nRead == (DWORD)-1)
&& GetLastError() == ERROR_OPERATION_ABORTED) {
nRead = 0;
}
*nCharsReadPtr = nRead;
return 0;
}
else
return GetLastError();
}
/*
*------------------------------------------------------------------------
*
* WriteConsoleChars --
|
<
|
|
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
|
if (result) {
if ((nRead == 0 || nRead == (DWORD)-1)
&& GetLastError() == ERROR_OPERATION_ABORTED) {
nRead = 0;
}
*nCharsReadPtr = nRead;
return 0;
} else
return GetLastError();
}
/*
*------------------------------------------------------------------------
*
* WriteConsoleChars --
|
| ︙ | | | ︙ | |
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
|
result = WriteConsoleW(hConsole, lpBuffer, nChars, &nCharsWritten, NULL);
if (result) {
if (nCharsWritten == (DWORD) -1) {
nCharsWritten = 0;
}
*nCharsWrittenPtr = nCharsWritten;
return 0;
}
else {
return GetLastError();
}
}
/*
*----------------------------------------------------------------------
*
|
<
|
|
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
|
result = WriteConsoleW(hConsole, lpBuffer, nChars, &nCharsWritten, NULL);
if (result) {
if (nCharsWritten == (DWORD) -1) {
nCharsWritten = 0;
}
*nCharsWrittenPtr = nCharsWritten;
return 0;
} else {
return GetLastError();
}
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | | | ︙ | |
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
|
AcquireSRWLockShared(&handleInfoPtr->lock);
/* Remember at most one of READABLE, WRITABLE set */
if (chanInfoPtr->watchMask & TCL_READABLE) {
if (RingBufferLength(&handleInfoPtr->buffer) > 0
|| handleInfoPtr->lastError != ERROR_SUCCESS) {
block = 0; /* Input data available */
}
}
else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
/* TCL_WRITABLE */
block = 0; /* Output space available */
}
}
ReleaseSRWLockShared(&handleInfoPtr->lock);
}
|
<
|
|
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
|
AcquireSRWLockShared(&handleInfoPtr->lock);
/* Remember at most one of READABLE, WRITABLE set */
if (chanInfoPtr->watchMask & TCL_READABLE) {
if (RingBufferLength(&handleInfoPtr->buffer) > 0
|| handleInfoPtr->lastError != ERROR_SUCCESS) {
block = 0; /* Input data available */
}
} else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
/* TCL_WRITABLE */
block = 0; /* Output space available */
}
}
ReleaseSRWLockShared(&handleInfoPtr->lock);
}
|
| ︙ | | | ︙ | |
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
|
AcquireSRWLockShared(&handleInfoPtr->lock);
/* Rememebr channel is read or write, never both */
if (chanInfoPtr->watchMask & TCL_READABLE) {
if (RingBufferLength(&handleInfoPtr->buffer) > 0
|| handleInfoPtr->lastError != ERROR_SUCCESS) {
needEvent = 1; /* Input data available or error/EOF */
}
}
else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
needEvent = 1; /* Output space available */
}
}
ReleaseSRWLockShared(&handleInfoPtr->lock);
}
|
<
|
|
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
|
AcquireSRWLockShared(&handleInfoPtr->lock);
/* Rememebr channel is read or write, never both */
if (chanInfoPtr->watchMask & TCL_READABLE) {
if (RingBufferLength(&handleInfoPtr->buffer) > 0
|| handleInfoPtr->lastError != ERROR_SUCCESS) {
needEvent = 1; /* Input data available or error/EOF */
}
} else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
needEvent = 1; /* Output space available */
}
}
ReleaseSRWLockShared(&handleInfoPtr->lock);
}
|
| ︙ | | | ︙ | |
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
|
* still close the handle. That's historical behavior on all platforms.
*/
if (!TclInThreadExit()
|| ((GetStdHandle(STD_INPUT_HANDLE) != chanInfoPtr->handle)
&& (GetStdHandle(STD_OUTPUT_HANDLE) != chanInfoPtr->handle)
&& (GetStdHandle(STD_ERROR_HANDLE) != chanInfoPtr->handle))) {
closeHandle = 1;
}
else {
closeHandle = 0;
}
AcquireSRWLockExclusive(&gConsoleLock);
/* Remove channel from watchers' list */
for (nextPtrPtr = &gWatchingChannelList; *nextPtrPtr != NULL;
|
<
|
|
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
|
* still close the handle. That's historical behavior on all platforms.
*/
if (!TclInThreadExit()
|| ((GetStdHandle(STD_INPUT_HANDLE) != chanInfoPtr->handle)
&& (GetStdHandle(STD_OUTPUT_HANDLE) != chanInfoPtr->handle)
&& (GetStdHandle(STD_ERROR_HANDLE) != chanInfoPtr->handle))) {
closeHandle = 1;
} else {
closeHandle = 0;
}
AcquireSRWLockExclusive(&gConsoleLock);
/* Remove channel from watchers' list */
for (nextPtrPtr = &gWatchingChannelList; *nextPtrPtr != NULL;
|
| ︙ | | | ︙ | |
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
|
* Note, we can check and manipulate numRefs without a lock because
* we have removed it from the watch queue so the console thread cannot
* get at it.
*/
if (chanInfoPtr->numRefs > 1) {
/* There may be references already on the event queue */
chanInfoPtr->numRefs -= 1;
}
else {
ckfree(chanInfoPtr);
}
return errorCode;
}
/*
|
<
|
|
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
|
* Note, we can check and manipulate numRefs without a lock because
* we have removed it from the watch queue so the console thread cannot
* get at it.
*/
if (chanInfoPtr->numRefs > 1) {
/* There may be references already on the event queue */
chanInfoPtr->numRefs -= 1;
} else {
ckfree(chanInfoPtr);
}
return errorCode;
}
/*
|
| ︙ | | | ︙ | |
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
|
* - If EOF, indicate as much. It is up to the application to close
* the channel.
* - Otherwise, if non-blocking return EAGAIN or wait for more data.
*/
if (handleInfoPtr->lastError != 0) {
if (handleInfoPtr->lastError == ERROR_INVALID_HANDLE) {
numRead = 0; /* Treat as EOF */
}
else {
Tcl_WinConvertError(handleInfoPtr->lastError);
handleInfoPtr->lastError = 0;
*errorCode = Tcl_GetErrno();
numRead = -1;
}
break;
}
|
<
|
|
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
|
* - If EOF, indicate as much. It is up to the application to close
* the channel.
* - Otherwise, if non-blocking return EAGAIN or wait for more data.
*/
if (handleInfoPtr->lastError != 0) {
if (handleInfoPtr->lastError == ERROR_INVALID_HANDLE) {
numRead = 0; /* Treat as EOF */
} else {
Tcl_WinConvertError(handleInfoPtr->lastError);
handleInfoPtr->lastError = 0;
*errorCode = Tcl_GetErrno();
numRead = -1;
}
break;
}
|
| ︙ | | | ︙ | |
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
|
bufSize / sizeof(WCHAR),
&numChars);
/* NOTE lock released so DON'T break. Return instead */
if (lastError != ERROR_SUCCESS) {
Tcl_WinConvertError(lastError);
*errorCode = Tcl_GetErrno();
return -1;
}
else if (numChars > 0) {
/* Successfully read something. */
return numChars * sizeof(WCHAR);
}
else {
/*
* Ctrl-C/Ctrl-Brk interrupt. Loop around to retry.
* We have to reacquire the lock. No worried about handleInfoPtr
* having gone away since the channel holds a reference.
*/
AcquireSRWLockExclusive(&handleInfoPtr->lock);
continue;
|
<
|
<
|
|
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
|
bufSize / sizeof(WCHAR),
&numChars);
/* NOTE lock released so DON'T break. Return instead */
if (lastError != ERROR_SUCCESS) {
Tcl_WinConvertError(lastError);
*errorCode = Tcl_GetErrno();
return -1;
} else if (numChars > 0) {
/* Successfully read something. */
return numChars * sizeof(WCHAR);
} else {
/*
* Ctrl-C/Ctrl-Brk interrupt. Loop around to retry.
* We have to reacquire the lock. No worried about handleInfoPtr
* having gone away since the channel holds a reference.
*/
AcquireSRWLockExclusive(&handleInfoPtr->lock);
continue;
|
| ︙ | | | ︙ | |
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
|
0)) {
/* Report the error */
Tcl_WinConvertError(GetLastError());
*errorCode = Tcl_GetErrno();
numWritten = -1;
break;
}
}
else {
/* Direct output */
DWORD winStatus;
HANDLE consoleHandle = handleInfoPtr->console;
/* Unlock before blocking in WriteConsole */
ReleaseSRWLockExclusive(&handleInfoPtr->lock);
/* UNLOCKED so return, DON'T break out of loop as it will unlock again! */
winStatus = WriteConsoleChars(consoleHandle,
(WCHAR *)buf,
toWrite / sizeof(WCHAR),
&numWritten);
if (winStatus == ERROR_SUCCESS) {
return numWritten * sizeof(WCHAR);
}
else {
Tcl_WinConvertError(winStatus);
*errorCode = Tcl_GetErrno();
return -1;
}
}
/* Lock is reacquired. Continue loop */
|
<
|
<
|
|
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
1336
|
0)) {
/* Report the error */
Tcl_WinConvertError(GetLastError());
*errorCode = Tcl_GetErrno();
numWritten = -1;
break;
}
} else {
/* Direct output */
DWORD winStatus;
HANDLE consoleHandle = handleInfoPtr->console;
/* Unlock before blocking in WriteConsole */
ReleaseSRWLockExclusive(&handleInfoPtr->lock);
/* UNLOCKED so return, DON'T break out of loop as it will unlock again! */
winStatus = WriteConsoleChars(consoleHandle,
(WCHAR *)buf,
toWrite / sizeof(WCHAR),
&numWritten);
if (winStatus == ERROR_SUCCESS) {
return numWritten * sizeof(WCHAR);
} else {
Tcl_WinConvertError(winStatus);
*errorCode = Tcl_GetErrno();
return -1;
}
}
/* Lock is reacquired. Continue loop */
|
| ︙ | | | ︙ | |
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
|
ConsoleHandleInfo *handleInfoPtr;
handleInfoPtr = FindConsoleInfo(chanInfoPtr);
if (handleInfoPtr == NULL) {
/* Console was closed. EOF->read event only (not write) */
if (chanInfoPtr->watchMask & TCL_READABLE) {
mask = TCL_READABLE;
}
}
else {
AcquireSRWLockShared(&handleInfoPtr->lock);
/* Remember at most one of READABLE, WRITABLE set */
if ((chanInfoPtr->watchMask & TCL_READABLE)
&& RingBufferLength(&handleInfoPtr->buffer)) {
mask = TCL_READABLE;
}
else if ((chanInfoPtr->watchMask & TCL_WRITABLE)
&& RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
/* Generate write event space available */
mask = TCL_WRITABLE;
}
ReleaseSRWLockShared(&handleInfoPtr->lock);
}
}
|
<
|
<
|
|
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
|
ConsoleHandleInfo *handleInfoPtr;
handleInfoPtr = FindConsoleInfo(chanInfoPtr);
if (handleInfoPtr == NULL) {
/* Console was closed. EOF->read event only (not write) */
if (chanInfoPtr->watchMask & TCL_READABLE) {
mask = TCL_READABLE;
}
} else {
AcquireSRWLockShared(&handleInfoPtr->lock);
/* Remember at most one of READABLE, WRITABLE set */
if ((chanInfoPtr->watchMask & TCL_READABLE)
&& RingBufferLength(&handleInfoPtr->buffer)) {
mask = TCL_READABLE;
} else if ((chanInfoPtr->watchMask & TCL_WRITABLE)
&& RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
/* Generate write event space available */
mask = TCL_WRITABLE;
}
ReleaseSRWLockShared(&handleInfoPtr->lock);
}
}
|
| ︙ | | | ︙ | |
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
|
/* No need to lock - see comments earlier */
/* Remove the reference to the channel from event record */
if (chanInfoPtr->numRefs > 1) {
chanInfoPtr->numRefs -= 1;
freeChannel = 0;
}
else {
assert(chanInfoPtr->channel == NULL);
freeChannel = 1;
}
if (freeChannel)
ckfree(chanInfoPtr);
return 1;
}
/*
*----------------------------------------------------------------------
*
|
<
|
|
>
|
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
|
/* No need to lock - see comments earlier */
/* Remove the reference to the channel from event record */
if (chanInfoPtr->numRefs > 1) {
chanInfoPtr->numRefs -= 1;
freeChannel = 0;
} else {
assert(chanInfoPtr->channel == NULL);
freeChannel = 1;
}
if (freeChannel) {
ckfree(chanInfoPtr);
}
return 1;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | | | ︙ | |
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
|
TCL_UNUSED(int) /*direction*/,
ClientData *handlePtr) /* Where to store the handle. */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
if (chanInfoPtr->handle == INVALID_HANDLE_VALUE) {
return TCL_ERROR;
}
else {
*handlePtr = chanInfoPtr->handle;
return TCL_OK;
}
}
/*
*------------------------------------------------------------------------
|
<
|
|
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
|
TCL_UNUSED(int) /*direction*/,
ClientData *handlePtr) /* Where to store the handle. */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
if (chanInfoPtr->handle == INVALID_HANDLE_VALUE) {
return TCL_ERROR;
} else {
*handlePtr = chanInfoPtr->handle;
return TCL_OK;
}
}
/*
*------------------------------------------------------------------------
|
| ︙ | | | ︙ | |
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
|
1);
inputOffset += nStored;
if (inputOffset == inputLen) {
/* Temp buffer now empty */
inputOffset = 0;
inputLen = 0;
}
}
else {
/*
* On error, nothing but inform caller and wait
* We do not want to exit until there are no client interps.
*/
}
/*
|
<
|
|
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
|
1);
inputOffset += nStored;
if (inputOffset == inputLen) {
/* Temp buffer now empty */
inputOffset = 0;
inputLen = 0;
}
} else {
/*
* On error, nothing but inform caller and wait
* We do not want to exit until there are no client interps.
*/
}
/*
|
| ︙ | | | ︙ | |
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
|
error = ReadConsoleChars(handleInfoPtr->console,
(WCHAR *)inputChars,
sizeof(inputChars) / sizeof(WCHAR),
&inputLen);
AcquireSRWLockExclusive(&handleInfoPtr->lock);
if (error == 0) {
inputLen *= sizeof(WCHAR);
}
else {
/*
* We only store the last error. It is up to channel
* handlers whether to close or not in case of errors.
*/
handleInfoPtr->lastError = error;
if (handleInfoPtr->lastError == ERROR_INVALID_HANDLE) {
handleInfoPtr->console = INVALID_HANDLE_VALUE;
}
}
}
else {
/*
* Either no one was asking for data, or no data was available.
* In the former case, wait until someone wakes us asking for
* data. In the latter case, there is no alternative but to
* poll since ReadConsole does not support async operation.
* So sleep for a short while and loop back to retry.
*/
|
<
|
<
|
|
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
|
error = ReadConsoleChars(handleInfoPtr->console,
(WCHAR *)inputChars,
sizeof(inputChars) / sizeof(WCHAR),
&inputLen);
AcquireSRWLockExclusive(&handleInfoPtr->lock);
if (error == 0) {
inputLen *= sizeof(WCHAR);
} else {
/*
* We only store the last error. It is up to channel
* handlers whether to close or not in case of errors.
*/
handleInfoPtr->lastError = error;
if (handleInfoPtr->lastError == ERROR_INVALID_HANDLE) {
handleInfoPtr->console = INVALID_HANDLE_VALUE;
}
}
} else {
/*
* Either no one was asking for data, or no data was available.
* In the former case, wait until someone wakes us asking for
* data. In the latter case, there is no alternative but to
* poll since ReadConsole does not support async operation.
* So sleep for a short while and loop back to retry.
*/
|
| ︙ | | | ︙ | |
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
|
chanInfoPtr->flags |= CONSOLE_READ_OPS;
GetConsoleMode(handle, &chanInfoPtr->initMode);
#ifdef OBSOLETE
/* Why was priority being set on console input? Code smell */
SetThreadPriority(infoPtr->reader.thread, THREAD_PRIORITY_HIGHEST);
#endif
}
else {
/* Already checked permissions is WRITABLE if not READABLE */
/* TODO - enable ansi escape processing? */
}
/*
* Global lock but that's ok. See comments top of file. Allocations
* will happen only a few times in the life of a process and that too
* generally at start up where only one thread is active.
*/
AcquireSRWLockExclusive(&gConsoleLock); /*Allocate needs exclusive lock */
handleInfoPtr = FindConsoleInfo(chanInfoPtr);
if (handleInfoPtr == NULL) {
/* Not found. Allocate one */
handleInfoPtr = AllocateConsoleHandleInfo(handle, permissions);
}
else {
/* Found. Its direction (read/write) better be the same */
if (handleInfoPtr->permissions != permissions) {
handleInfoPtr = NULL;
}
}
if (handleInfoPtr == NULL) {
|
<
|
<
|
|
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
|
chanInfoPtr->flags |= CONSOLE_READ_OPS;
GetConsoleMode(handle, &chanInfoPtr->initMode);
#ifdef OBSOLETE
/* Why was priority being set on console input? Code smell */
SetThreadPriority(infoPtr->reader.thread, THREAD_PRIORITY_HIGHEST);
#endif
} else {
/* Already checked permissions is WRITABLE if not READABLE */
/* TODO - enable ansi escape processing? */
}
/*
* Global lock but that's ok. See comments top of file. Allocations
* will happen only a few times in the life of a process and that too
* generally at start up where only one thread is active.
*/
AcquireSRWLockExclusive(&gConsoleLock); /*Allocate needs exclusive lock */
handleInfoPtr = FindConsoleInfo(chanInfoPtr);
if (handleInfoPtr == NULL) {
/* Not found. Allocate one */
handleInfoPtr = AllocateConsoleHandleInfo(handle, permissions);
} else {
/* Found. Its direction (read/write) better be the same */
if (handleInfoPtr->permissions != permissions) {
handleInfoPtr = NULL;
}
}
if (handleInfoPtr == NULL) {
|
| ︙ | | | ︙ | |
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
|
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
/* No need for any locks as no other thread will be writing to it */
if (action == TCL_CHANNEL_THREAD_INSERT) {
ConsoleInit(); /* Needed to set up event source handlers for this thread */
chanInfoPtr->threadId = Tcl_GetCurrentThread();
}
else {
chanInfoPtr->threadId = NULL;
}
}
/*
*----------------------------------------------------------------------
*
|
<
|
|
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
|
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
/* No need for any locks as no other thread will be writing to it */
if (action == TCL_CHANNEL_THREAD_INSERT) {
ConsoleInit(); /* Needed to set up event source handlers for this thread */
chanInfoPtr->threadId = Tcl_GetCurrentThread();
} else {
chanInfoPtr->threadId = NULL;
}
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | | | ︙ | |
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
|
} else {
Tcl_DStringAppendElement(dsPtr, "password");
}
} else {
Tcl_DStringAppendElement(dsPtr, "raw");
}
}
}
else {
/*
* Output channel. Get option -winsize
* Option is readonly and returned by [fconfigure chan -winsize] but not
* returned by [fconfigure chan] without explicit option name.
*/
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-winsize");
|
<
|
|
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
|
} else {
Tcl_DStringAppendElement(dsPtr, "password");
}
} else {
Tcl_DStringAppendElement(dsPtr, "raw");
}
}
} else {
/*
* Output channel. Get option -winsize
* Option is readonly and returned by [fconfigure chan -winsize] but not
* returned by [fconfigure chan] without explicit option name.
*/
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-winsize");
|
| ︙ | | | ︙ | |