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
OArgumentList()43 OArgumentList::OArgumentList() :
44 n_Args(0),
45 m_aVec(0)
46 {
47 // empty
48 }
49
OArgumentList(sal_uInt32 nArgs,const::rtl::OUString * aArgument1,...)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
OArgumentList(const rtl::OUString aArgumentList[],sal_uInt32 nArgs)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
OArgumentList(const OArgumentList & rOther)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
operator =(const OArgumentList & rOther)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
~OArgumentList()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
OEnvironment()130 OEnvironment::OEnvironment() :
131 n_Vars( 0 ),
132 m_aVec( 0 )
133 {
134 }
135
OEnvironment(sal_Int32 nVars,const::rtl::OUString * aArgument1,...)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
OEnvironment(const::rtl::OUString aVariableList[],sal_Int32 nVars)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
OEnvironment(const OEnvironment & rOther)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
operator =(const OEnvironment & rOther)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
~OEnvironment()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
OProcess()219 OProcess::OProcess( ) :
220 m_strImageName( ),
221 m_strDirectory(),
222 m_Process(0)
223 {
224 }
225
226
OProcess(const rtl::OUString & strImageName)227 OProcess::OProcess( const rtl::OUString& strImageName ) :
228 m_strImageName( strImageName ),
229 m_strDirectory(),
230 m_Process(0)
231 {
232 // empty
233 }
234
235
OProcess(const rtl::OUString & strImageName,const rtl::OUString & strWorkingDirectory)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
~OProcess()245 OProcess::~OProcess()
246 {
247 osl_freeProcessHandle(m_Process);
248 }
249
getProcess(TProcessIdentifier Identifier)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
execute(TProcessOption Options,const OArgumentList & aArgumentList,const OEnvironment & aEnvironment)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
execute(TProcessOption Options,const OSecurity & Security,const OArgumentList & aArgumentList,const OEnvironment & aEnvironment)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
terminate()300 OProcess::TProcessError OProcess::terminate()
301 {
302 return (TProcessError)osl_terminateProcess(m_Process);
303 }
304
getInfo(TProcessData Data,TProcessInfo * pInfo) const305 OProcess::TProcessError OProcess::getInfo(TProcessData Data, TProcessInfo* pInfo) const
306 {
307 return (TProcessError)osl_getProcessInfo(m_Process, Data, pInfo);
308 }
309
getCurrentInfo(TProcessData Data,TProcessInfo * pInfo)310 OProcess::TProcessError OProcess::getCurrentInfo(TProcessData Data, TProcessInfo* pInfo)
311 {
312 return (TProcessError)osl_getProcessInfo(0, Data, pInfo);
313 }
314
join()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
OStartupInfo()337 OStartupInfo::OStartupInfo()
338 {
339 }
340
~OStartupInfo()341 OStartupInfo::~OStartupInfo()
342 {
343 }
344
getExecutableFile(rtl::OUString & strImageName) const345 OStartupInfo::TStartupError OStartupInfo::getExecutableFile(
346 rtl::OUString& strImageName ) const
347 {
348 return (TStartupError) osl_getExecutableFile( &strImageName.pData );
349 }
350
351
getCommandArg(sal_uInt32 nArg,rtl::OUString & strCommandArg)352 OStartupInfo::TStartupError OStartupInfo::getCommandArg(sal_uInt32 nArg, rtl::OUString& strCommandArg)
353 {
354 return ( TStartupError ) osl_getCommandArg( nArg,&strCommandArg.pData );
355 }
356
getCommandArgCount()357 sal_uInt32 OStartupInfo::getCommandArgCount()
358 {
359 return osl_getCommandArgCount();
360 }
361
getEnvironment(const rtl::OUString & strVar,rtl::OUString & strValue)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
OExtCommandLineImpl()397 OExtCommandLineImpl::OExtCommandLineImpl()
398 : m_nArgCount(0)
399 {
400 init();
401 }
402
~OExtCommandLineImpl()403 OExtCommandLineImpl::~OExtCommandLineImpl()
404 {
405
406 }
407
408
getCommandArgCount()409 sal_uInt32 SAL_CALL OExtCommandLineImpl::getCommandArgCount()
410 {
411 return m_nArgCount;
412 }
413
414
getCommandArg(sal_uInt32 nArg,::rtl::OUString & strCommandArg)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
init()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
OExtCommandLine()495 OExtCommandLine::OExtCommandLine()
496 {
497 OGuard Guard(lclMutex::get());
498
499 if ( pExtImpl == NULL )
500 {
501 pExtImpl = new OExtCommandLineImpl;
502 }
503 }
504
~OExtCommandLine()505 OExtCommandLine::~OExtCommandLine()
506 {
507
508
509 }
510
getCommandArgCount()511 sal_uInt32 SAL_CALL OExtCommandLine::getCommandArgCount()
512 {
513 return pExtImpl->getCommandArgCount();
514 }
515
516
getCommandArg(sal_uInt32 nArg,::rtl::OUString & strCommandArg)517 sal_Bool SAL_CALL OExtCommandLine::getCommandArg(sal_uInt32 nArg, ::rtl::OUString& strCommandArg)
518 {
519 return pExtImpl->getCommandArg(nArg,strCommandArg);
520 }
521
522