xref: /trunk/main/vos/source/process.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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