mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
fixed handle inheritance and closing in win32 cli wrapper
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1057 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -69,7 +69,6 @@ void CLISetInterface::run() {
|
|||||||
// loop
|
// loop
|
||||||
running = true;
|
running = true;
|
||||||
while (running) {
|
while (running) {
|
||||||
if (!cli.canGetLine()) break;
|
|
||||||
// show prompt
|
// show prompt
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
cli << GRAY << _("> ") << NORMAL;
|
cli << GRAY << _("> ") << NORMAL;
|
||||||
@@ -77,6 +76,7 @@ void CLISetInterface::run() {
|
|||||||
}
|
}
|
||||||
// read line from stdin
|
// read line from stdin
|
||||||
String command = cli.getLine();
|
String command = cli.getLine();
|
||||||
|
if (command.empty() && !cli.canGetLine()) break;
|
||||||
handleCommand(command);
|
handleCommand(command);
|
||||||
cli.flush();
|
cli.flush();
|
||||||
cli.flushRaw();
|
cli.flushRaw();
|
||||||
|
|||||||
@@ -141,9 +141,9 @@ void TextIOHandler::flushRaw() {
|
|||||||
if (!buffer.empty()) {
|
if (!buffer.empty()) {
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
wxCharBuffer buf = buffer.mb_str(wxConvUTF8);
|
wxCharBuffer buf = buffer.mb_str(wxConvUTF8);
|
||||||
puts(buf);
|
fputs(buf,stdout);
|
||||||
#else
|
#else
|
||||||
puts(buffer.c_str());
|
fputs(buffer.c_str(),stdout);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
/// How to transfer data from one handle to another
|
/// How to transfer data from one handle to another
|
||||||
struct Transfer {
|
struct Transfer {
|
||||||
HANDLE from, to;
|
HANDLE from, &to;
|
||||||
bool escapes;
|
bool escapes;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,16 +103,10 @@ int main(int argc, char** argv) {
|
|||||||
// Ctrl+C handler
|
// Ctrl+C handler
|
||||||
SetConsoleCtrlHandler(HandleCtrlEvent, TRUE);
|
SetConsoleCtrlHandler(HandleCtrlEvent, TRUE);
|
||||||
|
|
||||||
// inheritable handles
|
|
||||||
SECURITY_ATTRIBUTES inherit;
|
|
||||||
inherit.nLength = sizeof(inherit);
|
|
||||||
inherit.bInheritHandle = true;
|
|
||||||
inherit.lpSecurityDescriptor = NULL;
|
|
||||||
|
|
||||||
// create pipes
|
// create pipes
|
||||||
CreatePipe(&in_theirs, &in_mine, &inherit, 0);
|
CreatePipe(&in_theirs, &in_mine, NULL, 0);
|
||||||
CreatePipe(&out_mine, &out_theirs, &inherit, 0);
|
CreatePipe(&out_mine, &out_theirs, NULL, 0);
|
||||||
CreatePipe(&err_mine, &err_theirs, &inherit, 0);
|
CreatePipe(&err_mine, &err_theirs, NULL, 0);
|
||||||
|
|
||||||
// the actual handles
|
// the actual handles
|
||||||
in_real = GetStdHandle(STD_INPUT_HANDLE);
|
in_real = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
@@ -128,10 +122,11 @@ int main(int argc, char** argv) {
|
|||||||
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_out,0,NULL);
|
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_out,0,NULL);
|
||||||
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_err,0,NULL);
|
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_err,0,NULL);
|
||||||
|
|
||||||
// give handles to child process
|
// give (inheritable copies of) handles to child process
|
||||||
child_startup_info.hStdInput = in_theirs;
|
HANDLE me = GetCurrentProcess();
|
||||||
child_startup_info.hStdOutput = out_theirs;
|
DuplicateHandle(me,in_theirs, me,&child_startup_info.hStdInput, 0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
|
||||||
child_startup_info.hStdError = err_theirs;
|
DuplicateHandle(me,out_theirs,me,&child_startup_info.hStdOutput,0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
|
||||||
|
DuplicateHandle(me,err_theirs,me,&child_startup_info.hStdError, 0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
|
||||||
child_startup_info.dwFlags = STARTF_USESTDHANDLES;
|
child_startup_info.dwFlags = STARTF_USESTDHANDLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,9 +154,13 @@ BOOL WINAPI HandleCtrlEvent(DWORD type) {
|
|||||||
DWORD exit_code = 1;
|
DWORD exit_code = 1;
|
||||||
// try to exit child process cleanly
|
// try to exit child process cleanly
|
||||||
// TODO: don't exit child on Ctrl+C
|
// TODO: don't exit child on Ctrl+C
|
||||||
CopyFileBuffer(in_mine,":quit\n",6);
|
bool wait = false;
|
||||||
CopyFileBuffer(out_real,":quit\n",6);
|
if (in_mine != INVALID_HANDLE_VALUE) {
|
||||||
if (WaitForSingleObject(child_process_info.hProcess,100) == WAIT_OBJECT_0) {
|
CopyFileBuffer(in_mine,":quit\n",6);
|
||||||
|
CopyFileBuffer(out_real,":quit\n",6);
|
||||||
|
wait = true;
|
||||||
|
}
|
||||||
|
if (wait && WaitForSingleObject(child_process_info.hProcess,100) == WAIT_OBJECT_0) {
|
||||||
GetExitCodeProcess(child_process_info.hProcess, &exit_code);
|
GetExitCodeProcess(child_process_info.hProcess, &exit_code);
|
||||||
} else {
|
} else {
|
||||||
TerminateProcess(child_process_info.hProcess,1);
|
TerminateProcess(child_process_info.hProcess,1);
|
||||||
@@ -177,7 +176,7 @@ BOOL WINAPI HandleCtrlEvent(DWORD type) {
|
|||||||
void CopyFileBuffer(HANDLE output, char* buffer, DWORD size) {
|
void CopyFileBuffer(HANDLE output, char* buffer, DWORD size) {
|
||||||
DWORD pos = 0, bytes_written;
|
DWORD pos = 0, bytes_written;
|
||||||
while (pos < size) {
|
while (pos < size) {
|
||||||
WriteFile(output, buffer + pos, size - pos, &bytes_written, NULL);
|
WriteFile(output, buffer + pos, size - pos, &bytes_written, NULL);
|
||||||
pos += bytes_written;
|
pos += bytes_written;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +222,13 @@ DWORD WINAPI TransferThread(Transfer* transfer) {
|
|||||||
// read
|
// read
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
DWORD bytes_read;
|
DWORD bytes_read;
|
||||||
ReadFile(transfer->from, buffer, sizeof(buffer), &bytes_read, NULL);
|
BOOL ok = ReadFile(transfer->from, buffer, sizeof(buffer), &bytes_read, NULL);
|
||||||
|
if (ok && bytes_read == 0) {
|
||||||
|
// end of file: close handle
|
||||||
|
CloseHandle(transfer->to);
|
||||||
|
transfer->to = INVALID_HANDLE_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
// write
|
// write
|
||||||
CopyFileBufferWithEscape(transfer->to, buffer, bytes_read, transfer->escapes);
|
CopyFileBufferWithEscape(transfer->to, buffer, bytes_read, transfer->escapes);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user