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