INTEGRATION: CWS sb86 (1.2.6); FILE MERGED
2008/03/27 10:42:53 sb 1.2.6.1: #i87491# lost unopkg.coms
This commit is contained in:
parent
022ad384a5
commit
9e6b7b25d2
2 changed files with 8 additions and 290 deletions
|
@ -7,7 +7,7 @@
|
|||
* OpenOffice.org - a multi-platform office productivity suite
|
||||
*
|
||||
* $RCSfile: guistdio.cxx,v $
|
||||
* $Revision: 1.3 $
|
||||
* $Revision: 1.4 $
|
||||
*
|
||||
* This file is part of OpenOffice.org.
|
||||
*
|
||||
|
@ -28,292 +28,6 @@
|
|||
*
|
||||
************************************************************************/
|
||||
|
||||
// MARKER(update_precomp.py): autogen include statement, do not remove
|
||||
#include "precompiled_desktop.hxx"
|
||||
|
||||
#define UNICODE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push,1) // disable warnings within system headers
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#define _UNICODE
|
||||
#include <tchar.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <systools/win32/uwinapi.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Thread that reads from child process standard output pipe
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DWORD WINAPI OutputThread( LPVOID pParam )
|
||||
{
|
||||
BYTE aBuffer[256];
|
||||
DWORD dwRead = 0;
|
||||
HANDLE hReadPipe = (HANDLE)pParam;
|
||||
|
||||
while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
|
||||
{
|
||||
BOOL fSuccess;
|
||||
DWORD dwWritten;
|
||||
|
||||
fSuccess = WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Thread that reads from child process standard error pipe
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DWORD WINAPI ErrorThread( LPVOID pParam )
|
||||
{
|
||||
BYTE aBuffer[256];
|
||||
DWORD dwRead = 0;
|
||||
HANDLE hReadPipe = (HANDLE)pParam;
|
||||
|
||||
while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
|
||||
{
|
||||
BOOL fSuccess;
|
||||
DWORD dwWritten;
|
||||
|
||||
fSuccess = WriteFile( GetStdHandle( STD_ERROR_HANDLE ), aBuffer, dwRead, &dwWritten, NULL );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Thread that writes to child process standard input pipe
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DWORD WINAPI InputThread( LPVOID pParam )
|
||||
{
|
||||
BYTE aBuffer[256];
|
||||
DWORD dwRead = 0;
|
||||
HANDLE hWritePipe = (HANDLE)pParam;
|
||||
|
||||
while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
|
||||
{
|
||||
BOOL fSuccess;
|
||||
DWORD dwWritten;
|
||||
|
||||
fSuccess = WriteFile( hWritePipe, aBuffer, dwRead, &dwWritten, NULL );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Thread that waits until child process reached input idle
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DWORD WINAPI WaitForUIThread( LPVOID pParam )
|
||||
{
|
||||
HANDLE hProcess = (HANDLE)pParam;
|
||||
|
||||
#ifndef GUISTDIO_KEEPRUNNING
|
||||
if ( !_tgetenv( TEXT("GUISTDIO_KEEPRUNNING") ) )
|
||||
WaitForInputIdle( hProcess, INFINITE );
|
||||
else
|
||||
#endif
|
||||
WaitForSingleObject( hProcess, INFINITE );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ctrl-Break handler that terminates the child process if Ctrl-C was pressed
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
HANDLE hTargetProcess = INVALID_HANDLE_VALUE;
|
||||
|
||||
BOOL WINAPI CtrlBreakHandler(
|
||||
DWORD // control signal type
|
||||
)
|
||||
{
|
||||
TerminateProcess( hTargetProcess, 255 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifdef __MINGW32__
|
||||
int main( int, char ** )
|
||||
#else
|
||||
int _tmain( int, _TCHAR ** )
|
||||
#endif
|
||||
{
|
||||
TCHAR szTargetFileName[MAX_PATH] = TEXT("");
|
||||
STARTUPINFO aStartupInfo;
|
||||
PROCESS_INFORMATION aProcessInfo;
|
||||
|
||||
ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
|
||||
aStartupInfo.cb = sizeof(aStartupInfo);
|
||||
aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
|
||||
|
||||
// Create an output pipe where the write end is inheritable
|
||||
|
||||
HANDLE hOutputRead, hOutputWrite;
|
||||
|
||||
if ( CreatePipe( &hOutputRead, &hOutputWrite, NULL, 0 ) )
|
||||
{
|
||||
HANDLE hTemp;
|
||||
|
||||
DuplicateHandle( GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
|
||||
CloseHandle( hOutputWrite );
|
||||
hOutputWrite = hTemp;
|
||||
|
||||
aStartupInfo.hStdOutput = hOutputWrite;
|
||||
}
|
||||
|
||||
// Create an error pipe where the write end is inheritable
|
||||
|
||||
HANDLE hErrorRead, hErrorWrite;
|
||||
|
||||
if ( CreatePipe( &hErrorRead, &hErrorWrite, NULL, 0 ) )
|
||||
{
|
||||
HANDLE hTemp;
|
||||
|
||||
DuplicateHandle( GetCurrentProcess(), hErrorWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
|
||||
CloseHandle( hErrorWrite );
|
||||
hErrorWrite = hTemp;
|
||||
|
||||
aStartupInfo.hStdError = hErrorWrite;
|
||||
}
|
||||
|
||||
// Create an input pipe where the read end is inheritable
|
||||
|
||||
HANDLE hInputRead, hInputWrite;
|
||||
|
||||
if ( CreatePipe( &hInputRead, &hInputWrite, NULL, 0 ) )
|
||||
{
|
||||
HANDLE hTemp;
|
||||
|
||||
DuplicateHandle( GetCurrentProcess(), hInputRead, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS );
|
||||
CloseHandle( hInputRead );
|
||||
hInputRead = hTemp;
|
||||
|
||||
aStartupInfo.hStdInput = hInputRead;
|
||||
}
|
||||
|
||||
// Get image path with same name but with .exe extension
|
||||
|
||||
TCHAR szModuleFileName[MAX_PATH];
|
||||
|
||||
GetModuleFileName( NULL, szModuleFileName, MAX_PATH );
|
||||
_TCHAR *lpLastDot = _tcsrchr( szModuleFileName, '.' );
|
||||
if ( lpLastDot && 0 == _tcsicmp( lpLastDot, _T(".COM") ) )
|
||||
{
|
||||
size_t len = lpLastDot - szModuleFileName;
|
||||
_tcsncpy( szTargetFileName, szModuleFileName, len );
|
||||
_tcsncpy( szTargetFileName + len, _T(".EXE"), sizeof(szTargetFileName)/sizeof(szTargetFileName[0]) - len );
|
||||
}
|
||||
|
||||
// Create process with same command line, environment and stdio handles which
|
||||
// are directed to the created pipes
|
||||
|
||||
BOOL fSuccess = CreateProcess(
|
||||
szTargetFileName,
|
||||
GetCommandLine(),
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&aStartupInfo,
|
||||
&aProcessInfo );
|
||||
|
||||
if ( fSuccess )
|
||||
{
|
||||
// These pipe ends are inherited by the child process and no longer used
|
||||
CloseHandle( hOutputWrite );
|
||||
CloseHandle( hErrorWrite );
|
||||
CloseHandle( hInputRead );
|
||||
|
||||
// Set the Ctrl-Break handler
|
||||
hTargetProcess = aProcessInfo.hProcess;
|
||||
SetConsoleCtrlHandler( CtrlBreakHandler, TRUE );
|
||||
|
||||
// Create threads that redirect remote pipe io to current process's console stdio
|
||||
|
||||
DWORD dwOutputThreadId, dwErrorThreadId, dwInputThreadId;
|
||||
|
||||
HANDLE hOutputThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hOutputRead, 0, &dwOutputThreadId );
|
||||
HANDLE hErrorThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hErrorRead, 0, &dwErrorThreadId );
|
||||
HANDLE hInputThread = CreateThread( NULL, 0, InputThread, (LPVOID)hInputWrite, 0, &dwInputThreadId );
|
||||
|
||||
// Create thread that wait until child process entered input idle
|
||||
|
||||
DWORD dwWaitForUIThreadId;
|
||||
HANDLE hWaitForUIThread = CreateThread( NULL, 0, WaitForUIThread, (LPVOID)aProcessInfo.hProcess, 0, &dwWaitForUIThreadId );
|
||||
|
||||
DWORD dwWaitResult;
|
||||
bool bDetach = false;
|
||||
int nOpenPipes = 3;
|
||||
HANDLE hObjects[] =
|
||||
{
|
||||
hTargetProcess,
|
||||
hWaitForUIThread,
|
||||
hInputThread,
|
||||
hOutputThread,
|
||||
hErrorThread
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
dwWaitResult = WaitForMultipleObjects( elementsof(hObjects), hObjects, FALSE, INFINITE );
|
||||
|
||||
switch ( dwWaitResult )
|
||||
{
|
||||
case WAIT_OBJECT_0: // The child process has terminated
|
||||
case WAIT_OBJECT_0 + 1: // The child process entered input idle
|
||||
bDetach = true;
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 2: // The remote end of stdin pipe was closed
|
||||
case WAIT_OBJECT_0 + 3: // The remote end of stdout pipe was closed
|
||||
case WAIT_OBJECT_0 + 4: // The remote end of stderr pipe was closed
|
||||
bDetach = --nOpenPipes <= 0;
|
||||
break;
|
||||
default: // Something went wrong
|
||||
bDetach = true;
|
||||
break;
|
||||
}
|
||||
} while( !bDetach );
|
||||
|
||||
//Even if the child process terminates it is not garanteed that all three pipe threads terminate
|
||||
//as tests have proven. The loop above will be typically terminate because the process has
|
||||
//terminated. Then the pipe threads may not have read all data from the pipes yet. When we close
|
||||
//the threads then data may be lost. For example running unopkg without arguments shall print out
|
||||
//the help text. Without this workaround some text would be missing.
|
||||
//ifdef only for unopkg
|
||||
#ifdef GUISTDIO_KEEPRUNNING
|
||||
Sleep(1000);
|
||||
#endif
|
||||
CloseHandle( hOutputThread );
|
||||
CloseHandle( hErrorThread );
|
||||
CloseHandle( hInputThread );
|
||||
CloseHandle( hWaitForUIThread );
|
||||
|
||||
DWORD dwExitCode = 0;
|
||||
GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode );
|
||||
CloseHandle( aProcessInfo.hProcess );
|
||||
CloseHandle( aProcessInfo.hThread );
|
||||
|
||||
return dwExitCode;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#include "guistdio.inc"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#
|
||||
# $RCSfile: makefile.mk,v $
|
||||
#
|
||||
# $Revision: 1.3 $
|
||||
# $Revision: 1.4 $
|
||||
#
|
||||
# This file is part of OpenOffice.org.
|
||||
#
|
||||
|
@ -47,12 +47,16 @@ CXXFLAGS+= $(LFS_CFLAGS)
|
|||
|
||||
# --- Files --------------------------------------------------------
|
||||
|
||||
OBJFILES=$(APP1OBJS)
|
||||
OBJFILES=$(APP1OBJS) $(APP2OBJS)
|
||||
|
||||
APP1NOSAL=TRUE
|
||||
APP1OBJS=$(OBJ)$/guistdio.obj
|
||||
APP1TARGET=$(TARGET)
|
||||
|
||||
APP2NOSAL=TRUE
|
||||
APP2OBJS=$(OBJ)$/unopkgio.obj
|
||||
APP2TARGET=unopkgio
|
||||
|
||||
# --- Targets ------------------------------------------------------
|
||||
|
||||
.INCLUDE : target.mk
|
||||
|
|
Loading…
Reference in a new issue