diff options
Diffstat (limited to 'basic/source/app/process.cxx')
-rw-r--r-- | basic/source/app/process.cxx | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/basic/source/app/process.cxx b/basic/source/app/process.cxx new file mode 100644 index 000000000000..aedfa4e5cac3 --- /dev/null +++ b/basic/source/app/process.cxx @@ -0,0 +1,246 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_basic.hxx" + + +#ifdef WNT +#include <tools/prewin.h> +#include "winbase.h" +#include <tools/postwin.h> +#endif +#include <tools/errcode.hxx> +#include <basic/sbxcore.hxx> +#include <tools/string.hxx> +#include <osl/file.hxx> +#include <osl/process.h> + +#include <basic/ttstrhlp.hxx> + +//#ifndef _BYTE_STRING_LIST +//DECLARE_LIST( ByteStringList, ByteString * ); +//#define _BYTE_STRING_LIST +//#endif + +#include <basic/process.hxx> + +Process::Process() +: m_nArgumentCount( 0 ) +, m_pArgumentList( NULL ) +, m_nEnvCount( 0 ) +, m_pEnvList( NULL ) +, m_aProcessName() +, m_pProcess( NULL ) +, bWasGPF( FALSE ) +, bHasBeenStarted( FALSE ) +{ +} + +#define FREE_USTRING_LIST( count, list ) \ + if ( count && list ) \ + { \ + for ( unsigned int i = 0; i < count; ++i ) \ + { \ + rtl_uString_release( list[i] ); \ + list[i] = NULL; \ + } \ + delete[] list; \ + } \ + count = 0; \ + list = NULL; + +Process::~Process() +{ + FREE_USTRING_LIST( m_nArgumentCount, m_pArgumentList ); + FREE_USTRING_LIST( m_nEnvCount, m_pEnvList ); + if ( m_pProcess ) + osl_freeProcessHandle( m_pProcess ); +} + + +BOOL Process::ImplIsRunning() +{ + if ( m_pProcess && bHasBeenStarted ) + { + oslProcessInfo aProcessInfo; + osl_getProcessInfo(m_pProcess, osl_Process_EXITCODE, &aProcessInfo ); + if ( !(aProcessInfo.Fields & osl_Process_EXITCODE) ) + return TRUE; + else + return FALSE; + } + else + return FALSE; +} + +long Process::ImplGetExitCode() +{ + if ( m_pProcess ) + { + oslProcessInfo aProcessInfo; + osl_getProcessInfo(m_pProcess, osl_Process_EXITCODE, &aProcessInfo ); + if ( !(aProcessInfo.Fields & osl_Process_EXITCODE) ) + SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT ); + return aProcessInfo.Code; + } + else + SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT ); + return 0; +} + + +//////////////////////////////////////////////////////////////////////////// + +void Process::SetImage( const String &aAppPath, const String &aAppParams, const Environment *pEnv ) +{ // Set image file of executable + if ( m_pProcess && ImplIsRunning() ) + SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT ); + else + { + FREE_USTRING_LIST( m_nArgumentCount, m_pArgumentList ); + FREE_USTRING_LIST( m_nEnvCount, m_pEnvList ); + osl_freeProcessHandle( m_pProcess ); + m_pProcess = NULL; + + xub_StrLen i, nCount = aAppParams.GetQuotedTokenCount( CUniString("\"\"" ), ' ' ); + ::rtl::OUString *pParamList = new ::rtl::OUString[nCount]; + + xub_StrLen nParamCount = 0; + for ( i = 0 ; i < nCount ; i++ ) + { + ::rtl::OUString aTemp = ::rtl::OUString(aAppParams.GetQuotedToken( i, CUniString("\"\"''" ), ' ' )); + if ( aTemp.getLength() ) + { + pParamList[nParamCount] = aTemp; + nParamCount++; + } + } + m_nArgumentCount = nParamCount; + m_pArgumentList = new rtl_uString*[m_nArgumentCount]; + for ( i = 0 ; i < m_nArgumentCount ; i++ ) + { + m_pArgumentList[i] = NULL; + rtl_uString_assign( &(m_pArgumentList[i]), pParamList[i].pData ); + } + delete [] pParamList; + + if ( pEnv ) + { + m_pEnvList = new rtl_uString*[pEnv->size()]; + + m_nEnvCount = 0; + Environment::const_iterator aIter = pEnv->begin(); + while ( aIter != pEnv->end() ) + { + ::rtl::OUString aTemp = ::rtl::OUString( (*aIter).first ); + aTemp += ::rtl::OUString::createFromAscii( "=" ); + aTemp += ::rtl::OUString( (*aIter).second ); + m_pEnvList[m_nEnvCount] = NULL; + rtl_uString_assign( &(m_pEnvList[m_nEnvCount]), aTemp.pData ); + m_nEnvCount++; + aIter++; + } + } + + ::rtl::OUString aNormalizedAppPath; + osl::FileBase::getFileURLFromSystemPath( ::rtl::OUString(aAppPath), aNormalizedAppPath ); + m_aProcessName = aNormalizedAppPath;; + bHasBeenStarted = FALSE; + + } +} + +BOOL Process::Start() +{ // Start program + BOOL bSuccess=FALSE; + if ( m_aProcessName.getLength() && !ImplIsRunning() ) + { + bWasGPF = FALSE; +#ifdef WNT +// sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); + sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX); + try + { +#endif + bSuccess = osl_executeProcess( + m_aProcessName.pData, + m_pArgumentList, + m_nArgumentCount, + osl_Process_SEARCHPATH + /*| osl_Process_DETACHED*/ + /*| osl_Process_WAIT*/, + NULL, + NULL, + m_pEnvList, + m_nEnvCount, + &m_pProcess ) == osl_Process_E_None; + +#ifdef WNT + } + catch( ... ) + { + bWasGPF = TRUE; + // TODO: Output debug message !! + } + nErrorMode = SetErrorMode(nErrorMode); +#endif + bHasBeenStarted = bSuccess; + } + else + SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT ); + return bSuccess; +} + +ULONG Process::GetExitCode() +{ // ExitCode of program after execution + return ImplGetExitCode(); +} + +BOOL Process::IsRunning() +{ + return ImplIsRunning(); +} + +BOOL Process::WasGPF() +{ // Did the process fail? +#ifdef WNT + return ImplGetExitCode() == 3221225477; +#else + return bWasGPF; +#endif +} + +BOOL Process::Terminate() +{ + if ( ImplIsRunning() ) + return osl_terminateProcess(m_pProcess) == osl_Process_E_None; + return TRUE; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |