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