1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/*
* tclWinConsole.c --
*
* This file implements the Windows-specific console functions,
* and the "console" channel driver.
*
* Copyright (c) 1999 by Scriptics Corp.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclWinConsole.c,v 1.3.10.1 2000/07/27 01:39:25 hobbs Exp $
*/
#include "tclWinInt.h"
#include <dos.h>
#include <fcntl.h>
#include <io.h>
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/*
* tclWinConsole.c --
*
* This file implements the Windows-specific console functions,
* and the "console" channel driver.
*
* Copyright (c) 1999 by Scriptics Corp.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclWinConsole.c,v 1.3.10.2 2001/04/03 22:54:39 hobbs Exp $
*/
#include "tclWinInt.h"
#include <dos.h>
#include <fcntl.h>
#include <io.h>
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
* pointer. */
} ConsoleEvent;
/*
* Declarations for functions used only in this file.
*/
static int ApplicationType(Tcl_Interp *interp,
const char *fileName, char *fullName);
static void BuildCommandLine(const char *executable, int argc,
char **argv, Tcl_DString *linePtr);
static void CopyChannel(HANDLE dst, HANDLE src);
static BOOL HasConsole(void);
static TclFile MakeFile(HANDLE handle);
static char * MakeTempFile(Tcl_DString *namePtr);
static int ConsoleBlockModeProc(ClientData instanceData, int mode);
static void ConsoleCheckProc(ClientData clientData, int flags);
static int ConsoleCloseProc(ClientData instanceData,
Tcl_Interp *interp);
static int ConsoleEventProc(Tcl_Event *evPtr, int flags);
static void ConsoleExitHandler(ClientData clientData);
static int ConsoleGetHandleProc(ClientData instanceData,
int direction, ClientData *handlePtr);
static ThreadSpecificData *ConsoleInit(void);
static int ConsoleInputProc(ClientData instanceData, char *buf,
int toRead, int *errorCode);
static int ConsoleOutputProc(ClientData instanceData, char *buf,
int toWrite, int *errorCode);
static DWORD WINAPI ConsoleReaderThread(LPVOID arg);
static void ConsoleSetupProc(ClientData clientData, int flags);
static void ConsoleWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI ConsoleWriterThread(LPVOID arg);
static void ProcExitHandler(ClientData clientData);
static int TempFileName(WCHAR name[MAX_PATH]);
static int WaitForRead(ConsoleInfo *infoPtr, int blocking);
/*
* This structure describes the channel type structure for command console
* based IO.
*/
|
<
<
<
<
<
<
<
<
<
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
* pointer. */
} ConsoleEvent;
/*
* Declarations for functions used only in this file.
*/
static int ConsoleBlockModeProc(ClientData instanceData, int mode);
static void ConsoleCheckProc(ClientData clientData, int flags);
static int ConsoleCloseProc(ClientData instanceData,
Tcl_Interp *interp);
static int ConsoleEventProc(Tcl_Event *evPtr, int flags);
static void ConsoleExitHandler(ClientData clientData);
static int ConsoleGetHandleProc(ClientData instanceData,
int direction, ClientData *handlePtr);
static ThreadSpecificData *ConsoleInit(void);
static int ConsoleInputProc(ClientData instanceData, char *buf,
int toRead, int *errorCode);
static int ConsoleOutputProc(ClientData instanceData, char *buf,
int toWrite, int *errorCode);
static DWORD WINAPI ConsoleReaderThread(LPVOID arg);
static void ConsoleSetupProc(ClientData clientData, int flags);
static void ConsoleWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI ConsoleWriterThread(LPVOID arg);
static void ProcExitHandler(ClientData clientData);
static int WaitForRead(ConsoleInfo *infoPtr, int blocking);
/*
* This structure describes the channel type structure for command console
* based IO.
*/
|
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
|
if (infoPtr->readFlags & CONSOLE_BUFFERED) {
/*
* Data is stored in the buffer.
*/
if (bufSize < (infoPtr->bytesRead - infoPtr->offset)) {
memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
bytesRead = bufSize;
infoPtr->offset += bufSize;
} else {
memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
bytesRead = infoPtr->bytesRead - infoPtr->offset;
/*
* Reset the buffer
*/
infoPtr->readFlags &= ~CONSOLE_BUFFERED;
|
|
|
|
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
|
if (infoPtr->readFlags & CONSOLE_BUFFERED) {
/*
* Data is stored in the buffer.
*/
if (bufSize < (infoPtr->bytesRead - infoPtr->offset)) {
memcpy(buf, &infoPtr->buffer[infoPtr->offset], (size_t) bufSize);
bytesRead = bufSize;
infoPtr->offset += bufSize;
} else {
memcpy(buf, &infoPtr->buffer[infoPtr->offset], (size_t) bufSize);
bytesRead = infoPtr->bytesRead - infoPtr->offset;
/*
* Reset the buffer
*/
infoPtr->readFlags &= ~CONSOLE_BUFFERED;
|
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
|
* Reallocate the buffer to be large enough to hold the data.
*/
if (infoPtr->writeBuf) {
ckfree(infoPtr->writeBuf);
}
infoPtr->writeBufLen = toWrite;
infoPtr->writeBuf = ckalloc(toWrite);
}
memcpy(infoPtr->writeBuf, buf, toWrite);
infoPtr->toWrite = toWrite;
ResetEvent(infoPtr->writable);
SetEvent(infoPtr->startWriter);
bytesWritten = toWrite;
} else {
/*
* In the blocking case, just try to write the buffer directly.
|
|
|
|
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
|
* Reallocate the buffer to be large enough to hold the data.
*/
if (infoPtr->writeBuf) {
ckfree(infoPtr->writeBuf);
}
infoPtr->writeBufLen = toWrite;
infoPtr->writeBuf = ckalloc((unsigned int) toWrite);
}
memcpy(infoPtr->writeBuf, buf, (size_t) toWrite);
infoPtr->toWrite = toWrite;
ResetEvent(infoPtr->writable);
SetEvent(infoPtr->startWriter);
bytesWritten = toWrite;
} else {
/*
* In the blocking case, just try to write the buffer directly.
|
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
|
count = 0;
/*
* Look for data on the console, but first ignore any events
* that are not KEY_EVENTs
*/
if (ReadConsole(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE,
&infoPtr->bytesRead, NULL) != FALSE) {
/*
* Data was stored in the buffer.
*/
infoPtr->readFlags |= CONSOLE_BUFFERED;
} else {
DWORD err;
|
|
|
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
|
count = 0;
/*
* Look for data on the console, but first ignore any events
* that are not KEY_EVENTs
*/
if (ReadConsole(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE,
(LPDWORD) &infoPtr->bytesRead, NULL) != FALSE) {
/*
* Data was stored in the buffer.
*/
infoPtr->readFlags |= CONSOLE_BUFFERED;
} else {
DWORD err;
|