1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 29 #include <cstdarg> 30 #include <vector> 31 #include <rtl/ustring.hxx> 32 #include <rtl/instance.hxx> 33 34 #include "vos/process.hxx" 35 #include "vos/diagnose.hxx" 36 #include <osl/file.hxx> 37 38 #define MAX_RESOURCES 100 39 #define MAX_ARGS 100 40 #define MAX_ENVIROMENTS 100 41 42 using namespace vos; 43 44 ///////////////////////////////////////////////////////////////////////////// 45 /// Argument 46 47 OArgumentList::OArgumentList() : 48 n_Args(0), 49 m_aVec(0) 50 { 51 // empty 52 } 53 54 OArgumentList::OArgumentList( sal_uInt32 nArgs, const ::rtl::OUString* aArgument1, ... ) : 55 n_Args( nArgs ) 56 { 57 m_aVec = new rtl_uString* [nArgs]; 58 std::va_list pArgs; 59 sal_uInt32 i = 0; 60 const rtl::OUString* aArgument; 61 62 va_start ( pArgs, aArgument1 ); 63 aArgument = aArgument1; 64 65 while( true ) { 66 m_aVec[i] = aArgument->pData; 67 rtl_uString_acquire( m_aVec[i++] ); 68 if( i < n_Args ) 69 aArgument = va_arg( pArgs,rtl::OUString* ); 70 else 71 break; 72 } 73 va_end( pArgs ); 74 } 75 76 77 OArgumentList::OArgumentList( const rtl::OUString aArgumentList[], sal_uInt32 nArgs ) : 78 n_Args( nArgs ) 79 { 80 m_aVec = new rtl_uString* [n_Args]; 81 for( sal_uInt32 i = 0; i < n_Args; ++ i ) { 82 m_aVec[i] = aArgumentList[i].pData; 83 rtl_uString_acquire( m_aVec[i] ); 84 } 85 } 86 87 OArgumentList::OArgumentList( const OArgumentList& rOther ) : n_Args( rOther.n_Args ) 88 { 89 m_aVec = new rtl_uString* [n_Args]; 90 91 sal_uInt32 i; 92 for ( i = 0; i < n_Args; ++i ) 93 { 94 m_aVec[i] = rOther.m_aVec[i]; 95 rtl_uString_acquire( m_aVec[i] ); 96 } 97 } 98 99 OArgumentList& OArgumentList::operator=( const OArgumentList& rOther ) 100 { 101 if ( this != &rOther ) 102 { 103 104 // delete the old one 105 sal_uInt32 i; 106 for ( i = 0; i < n_Args; ++i ) 107 rtl_uString_release( m_aVec[i] ); 108 109 delete [] m_aVec; 110 111 112 n_Args = rOther.n_Args; 113 m_aVec = new rtl_uString* [n_Args]; 114 for( i = 0; i < n_Args; ++i ) 115 { 116 m_aVec[i] = rOther.m_aVec[i]; 117 rtl_uString_acquire( m_aVec[i] ); 118 } 119 } 120 121 return *this; 122 } 123 124 OArgumentList::~OArgumentList( ) 125 { 126 for( sal_uInt32 i = 0; i < n_Args; ++i ) rtl_uString_release( m_aVec[i] ); 127 delete[] m_aVec; 128 } 129 130 131 //////////////////////////////////////////////////////////////////////////////// 132 /// Environment 133 134 OEnvironment::OEnvironment() : 135 n_Vars( 0 ), 136 m_aVec( 0 ) 137 { 138 } 139 140 OEnvironment::OEnvironment( sal_Int32 nVars, const ::rtl::OUString* aArgument1, ... ) : 141 n_Vars( nVars ) 142 { 143 m_aVec = new rtl_uString* [nVars]; 144 std::va_list pArgs; 145 sal_Int32 i = 0; 146 const rtl::OUString* aArgument; 147 148 va_start ( pArgs, aArgument1 ); 149 aArgument = aArgument1; 150 151 while( true ) { 152 m_aVec[i] = aArgument->pData; 153 rtl_uString_acquire( m_aVec[i++] ); 154 if( i < n_Vars ) 155 aArgument = va_arg( pArgs,rtl::OUString* ); 156 else 157 break; 158 } 159 va_end( pArgs ); 160 } 161 162 163 OEnvironment::OEnvironment( const ::rtl::OUString aVariableList[], sal_Int32 nVars ) : 164 n_Vars( nVars ) 165 { 166 m_aVec = new rtl_uString* [n_Vars]; 167 for( sal_Int32 i = 0; i < n_Vars; ++ i ) { 168 m_aVec[i] = aVariableList[i].pData; 169 rtl_uString_acquire( m_aVec[i] ); 170 } 171 } 172 173 OEnvironment::OEnvironment( const OEnvironment& rOther ) : n_Vars( rOther.n_Vars ) 174 { 175 m_aVec = new rtl_uString* [n_Vars]; 176 177 sal_Int32 i; 178 for ( i = 0; i < n_Vars; ++i ) 179 { 180 m_aVec[i] = rOther.m_aVec[i]; 181 rtl_uString_acquire( m_aVec[i] ); 182 } 183 } 184 185 OEnvironment& OEnvironment::operator=( const OEnvironment& rOther ) 186 { 187 if ( this != &rOther ) 188 { 189 sal_Int32 i; 190 for ( i = 0; i < n_Vars; ++i ) 191 rtl_uString_release( m_aVec[i] ); 192 193 delete [] m_aVec; 194 195 n_Vars = rOther.n_Vars; 196 m_aVec = new rtl_uString* [n_Vars]; 197 for ( i = 0; i < n_Vars; ++i ) 198 { 199 m_aVec[i] = rOther.m_aVec[i]; 200 rtl_uString_acquire( m_aVec[i] ); 201 } 202 } 203 204 return *this; 205 } 206 207 OEnvironment::~OEnvironment() 208 { 209 for( sal_Int32 i = 0; i < n_Vars; ++i ) rtl_uString_release( m_aVec[i] ); 210 delete[] m_aVec; 211 } 212 213 ///////////////////////////////////////////////////////////////////////////// 214 // Process 215 216 217 VOS_IMPLEMENT_CLASSINFO( 218 VOS_CLASSNAME(OProcess, vos), 219 VOS_NAMESPACE(OProcess, vos), 220 VOS_NAMESPACE(OObject, vos), 0); 221 222 223 OProcess::OProcess( ) : 224 m_strImageName( ), 225 m_strDirectory(), 226 m_Process(0) 227 { 228 } 229 230 231 OProcess::OProcess( const rtl::OUString& strImageName ) : 232 m_strImageName( strImageName ), 233 m_strDirectory(), 234 m_Process(0) 235 { 236 // empty 237 } 238 239 240 OProcess::OProcess(const rtl::OUString& strImageName, const rtl::OUString& strWorkingDirectory) : 241 m_strImageName( strImageName ), 242 m_strDirectory( strWorkingDirectory ), 243 m_Process(0) 244 { 245 // empty 246 } 247 248 249 OProcess::~OProcess() 250 { 251 osl_freeProcessHandle(m_Process); 252 } 253 254 OProcess* OProcess::getProcess(TProcessIdentifier Identifier) 255 { 256 oslProcess hProcess = osl_getProcess(Identifier); 257 258 if (hProcess) 259 { 260 OProcess* pProcess = new OProcess( ); 261 262 pProcess->m_Process = hProcess; 263 264 return pProcess; 265 } 266 267 return 0; 268 } 269 270 271 OProcess::TProcessError OProcess::execute(TProcessOption Options, 272 const OArgumentList& aArgumentList, 273 const OEnvironment& aEnvironment ) 274 { 275 return ((TProcessError)osl_executeProcess(m_strImageName.pData, 276 aArgumentList.m_aVec, 277 aArgumentList.n_Args, 278 Options, 279 0, 280 m_strDirectory.pData, 281 aEnvironment.m_aVec, 282 aEnvironment.n_Vars, 283 &m_Process)); 284 } 285 286 287 OProcess::TProcessError OProcess::execute( TProcessOption Options, 288 const OSecurity &Security, 289 const OArgumentList& aArgumentList, 290 const OEnvironment& aEnvironment ) 291 { 292 return ((TProcessError)osl_executeProcess(m_strImageName.pData, 293 aArgumentList.m_aVec, 294 aArgumentList.n_Args, 295 Options, 296 Security, 297 m_strDirectory.pData, 298 aEnvironment.m_aVec, 299 aEnvironment.n_Vars, 300 &m_Process)); 301 } 302 303 304 OProcess::TProcessError OProcess::terminate() 305 { 306 return (TProcessError)osl_terminateProcess(m_Process); 307 } 308 309 OProcess::TProcessError OProcess::getInfo(TProcessData Data, TProcessInfo* pInfo) const 310 { 311 return (TProcessError)osl_getProcessInfo(m_Process, Data, pInfo); 312 } 313 314 OProcess::TProcessError OProcess::getCurrentInfo(TProcessData Data, TProcessInfo* pInfo) 315 { 316 return (TProcessError)osl_getProcessInfo(0, Data, pInfo); 317 } 318 319 OProcess::TProcessError OProcess::join() 320 { 321 return (TProcessError)osl_joinProcess(m_Process); 322 } 323 324 325 /* 326 OProcess::TProcessError OProcess::searchPath(const sal_Char* Name, sal_Char *Buffer, sal_uInt32 Max, 327 const sal_Char* Path, sal_Char Separator) 328 { 329 return (TProcessError)osl_searchPath(Name, Path, Separator, Buffer, Max); 330 } 331 */ 332 333 ///////////////////////////////////////////////////////////////////////////// 334 // StartupInfo 335 336 VOS_IMPLEMENT_CLASSINFO( 337 VOS_CLASSNAME(OStartupInfo, vos), 338 VOS_NAMESPACE(OStartupInfo, vos), 339 VOS_NAMESPACE(OObject, vos), 0); 340 341 OStartupInfo::OStartupInfo() 342 { 343 } 344 345 OStartupInfo::~OStartupInfo() 346 { 347 } 348 349 OStartupInfo::TStartupError OStartupInfo::getExecutableFile( 350 rtl::OUString& strImageName ) const 351 { 352 return (TStartupError) osl_getExecutableFile( &strImageName.pData ); 353 } 354 355 356 OStartupInfo::TStartupError OStartupInfo::getCommandArg(sal_uInt32 nArg, rtl::OUString& strCommandArg) 357 { 358 return ( TStartupError ) osl_getCommandArg( nArg,&strCommandArg.pData ); 359 } 360 361 sal_uInt32 OStartupInfo::getCommandArgCount() 362 { 363 return osl_getCommandArgCount(); 364 } 365 366 OStartupInfo::TStartupError OStartupInfo::getEnvironment(const rtl::OUString& strVar, 367 rtl::OUString& strValue) 368 { 369 return ( TStartupError ) osl_getEnvironment( strVar.pData, &strValue.pData ); 370 } 371 372 373 374 ///////////////////////////////////////////////////////////////////////////// 375 // 376 // OExtCommandLineImpl 377 // 378 379 namespace vos 380 { 381 382 class OExtCommandLineImpl 383 { 384 void init(); 385 386 ::std::vector< ::rtl::OUString > aExtArgVector; 387 sal_uInt32 m_nArgCount; 388 389 public: 390 391 OExtCommandLineImpl(); 392 ~OExtCommandLineImpl(); 393 394 sal_uInt32 SAL_CALL getCommandArgCount(); 395 396 sal_Bool SAL_CALL getCommandArg(sal_uInt32 nArg, ::rtl::OUString& strCommandArg); 397 }; 398 399 } 400 401 OExtCommandLineImpl::OExtCommandLineImpl() 402 : m_nArgCount(0) 403 { 404 init(); 405 } 406 407 OExtCommandLineImpl::~OExtCommandLineImpl() 408 { 409 410 } 411 412 413 sal_uInt32 SAL_CALL OExtCommandLineImpl::getCommandArgCount() 414 { 415 return m_nArgCount; 416 } 417 418 419 sal_Bool SAL_CALL OExtCommandLineImpl::getCommandArg(sal_uInt32 nArg, ::rtl::OUString& strCommandArg) 420 { 421 if ( nArg >= m_nArgCount ) 422 { 423 return sal_False; 424 } 425 426 strCommandArg = aExtArgVector[nArg]; 427 428 return sal_True; 429 } 430 431 432 void OExtCommandLineImpl::init() 433 { 434 OStartupInfo aStartInfo; 435 sal_uInt32 nIndex=0; 436 sal_uInt32 nArgs = aStartInfo.getCommandArgCount(); 437 438 for ( nIndex = 0 ; nIndex < nArgs ; ++nIndex ) 439 { 440 ::rtl::OUString aString; 441 aStartInfo.getCommandArg(nIndex,aString); 442 443 if ( aString[0] == (sal_Unicode) '@' ) 444 { 445 ::rtl::OUString aFileName = aString.copy(1); 446 ::osl::File aFile(aFileName); 447 ::rtl::ByteSequence aSeq; 448 449 ::osl::FileBase::RC aErr = aFile.open(OpenFlag_Read); 450 451 if ( aErr != ::osl::FileBase::E_None ) 452 { 453 break; 454 } 455 456 do 457 { 458 aErr = aFile.readLine(aSeq); 459 if ( aSeq.getLength() != 0 ) 460 { 461 ::rtl::OUString newString((sal_Char*)aSeq.getArray(), aSeq.getLength(), RTL_TEXTENCODING_ASCII_US); 462 aExtArgVector.push_back( newString ); 463 m_nArgCount++; 464 } 465 } 466 while ( aErr == ::osl::FileBase::E_None && aSeq.getLength() > 0 ); 467 468 aFile.close(); 469 aFile.remove(aFileName); 470 } 471 else 472 { 473 aExtArgVector.push_back( aString ); 474 m_nArgCount++; 475 } 476 } 477 } 478 479 480 481 ///////////////////////////////////////////////////////////////////////////// 482 // 483 // OExtCommandLine 484 // 485 486 namespace 487 { 488 struct lclMutex : public rtl::Static< vos::OMutex, lclMutex > {}; 489 } 490 491 OExtCommandLineImpl* OExtCommandLine::pExtImpl=0; 492 493 494 VOS_IMPLEMENT_CLASSINFO( 495 VOS_CLASSNAME(OExtCommandLine, vos), 496 VOS_NAMESPACE(OExtCommandLine, vos), 497 VOS_NAMESPACE(OObject, vos), 0); 498 499 OExtCommandLine::OExtCommandLine() 500 { 501 OGuard Guard(lclMutex::get()); 502 503 if ( pExtImpl == NULL ) 504 { 505 pExtImpl = new OExtCommandLineImpl; 506 } 507 } 508 509 OExtCommandLine::~OExtCommandLine() 510 { 511 512 513 } 514 515 sal_uInt32 SAL_CALL OExtCommandLine::getCommandArgCount() 516 { 517 return pExtImpl->getCommandArgCount(); 518 } 519 520 521 sal_Bool SAL_CALL OExtCommandLine::getCommandArg(sal_uInt32 nArg, ::rtl::OUString& strCommandArg) 522 { 523 return pExtImpl->getCommandArg(nArg,strCommandArg); 524 } 525 526