xref: /aoo41x/main/sal/qa/osl/process/osl_process.cxx (revision 87d2adbc)
1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*87d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*87d2adbcSAndrew Rist  * distributed with this work for additional information
6*87d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*87d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*87d2adbcSAndrew Rist  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*87d2adbcSAndrew Rist  *
13*87d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist  * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*87d2adbcSAndrew Rist  * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist  * under the License.
19*87d2adbcSAndrew Rist  *
20*87d2adbcSAndrew Rist  *************************************************************/
21*87d2adbcSAndrew Rist 
22*87d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sal.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <testshl/simpleheader.hxx>
28cdf0e10cSrcweir #include <osl/process.h>
29cdf0e10cSrcweir #include <osl/file.hxx>
30cdf0e10cSrcweir #include <osl/thread.h>
31cdf0e10cSrcweir #include <rtl/ustring.hxx>
32cdf0e10cSrcweir #include <unistd.h>
33cdf0e10cSrcweir #include <signal.h>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <stdio.h>
36cdf0e10cSrcweir #include <stdlib.h>
37cdf0e10cSrcweir #include <osl/module.hxx>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #if ( defined WNT )                     // Windows
40cdf0e10cSrcweir #include <tools/prewin.h>
41cdf0e10cSrcweir #	define WIN32_LEAN_AND_MEAN
42cdf0e10cSrcweir // #	include <windows.h>
43cdf0e10cSrcweir #   include <tchar.h>
44cdf0e10cSrcweir #include <tools/postwin.h>
45cdf0e10cSrcweir #endif
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include "rtl/allocator.hxx"
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #include <iostream>
50cdf0e10cSrcweir #include <fstream>
51cdf0e10cSrcweir #include <vector>
52cdf0e10cSrcweir #include <algorithm>
53cdf0e10cSrcweir #include <iterator>
54cdf0e10cSrcweir #include <string>
55cdf0e10cSrcweir 
56cdf0e10cSrcweir #if defined(WNT) || defined(OS2)
57cdf0e10cSrcweir 	const rtl::OUString EXECUTABLE_NAME = rtl::OUString::createFromAscii("osl_process_child.exe");
58cdf0e10cSrcweir #else
59cdf0e10cSrcweir 	const rtl::OUString EXECUTABLE_NAME = rtl::OUString::createFromAscii("osl_process_child");
60cdf0e10cSrcweir #endif
61cdf0e10cSrcweir 
62cdf0e10cSrcweir 
63cdf0e10cSrcweir //########################################
64cdf0e10cSrcweir std::string OUString_to_std_string(const rtl::OUString& oustr)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir     rtl::OString ostr = rtl::OUStringToOString(oustr, osl_getThreadTextEncoding());
67cdf0e10cSrcweir     return std::string(ostr.getStr());
68cdf0e10cSrcweir }
69cdf0e10cSrcweir 
70cdf0e10cSrcweir //########################################
71cdf0e10cSrcweir using namespace osl;
72cdf0e10cSrcweir using namespace rtl;
73cdf0e10cSrcweir 
74cdf0e10cSrcweir /** print a UNI_CODE String.
75cdf0e10cSrcweir */
76cdf0e10cSrcweir inline void printUString( const ::rtl::OUString & str )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir 	rtl::OString aString;
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 	t_print("#printUString_u# " );
81cdf0e10cSrcweir 	aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US );
82cdf0e10cSrcweir 	t_print("%s\n", aString.getStr( ) );
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir /** get binary Path.
86cdf0e10cSrcweir */
87cdf0e10cSrcweir inline ::rtl::OUString getExecutablePath( void )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir 	::rtl::OUString dirPath;
90cdf0e10cSrcweir 	osl::Module::getUrlFromAddress( ( void* ) &getExecutablePath, dirPath );
91cdf0e10cSrcweir 	dirPath = dirPath.copy( 0, dirPath.lastIndexOf('/') );
92cdf0e10cSrcweir 	dirPath = dirPath.copy( 0, dirPath.lastIndexOf('/') + 1);
93cdf0e10cSrcweir 	dirPath += rtl::OUString::createFromAscii("bin");
94cdf0e10cSrcweir 	return dirPath;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir //rtl::OUString CWD = getExecutablePath();
98cdf0e10cSrcweir 
99cdf0e10cSrcweir //########################################
100cdf0e10cSrcweir class Test_osl_joinProcess : public CppUnit::TestFixture
101cdf0e10cSrcweir {
102cdf0e10cSrcweir     const OUString join_param_;
103cdf0e10cSrcweir     const OUString wait_time_;
104cdf0e10cSrcweir     OUString suCWD;
105cdf0e10cSrcweir     OUString suExecutableFileURL;
106cdf0e10cSrcweir 
107cdf0e10cSrcweir     rtl_uString* parameters_[2];
108cdf0e10cSrcweir     int          parameters_count_;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir public:
111cdf0e10cSrcweir 
112cdf0e10cSrcweir     Test_osl_joinProcess() :
113cdf0e10cSrcweir         join_param_(OUString::createFromAscii("-join")),
114cdf0e10cSrcweir         wait_time_(OUString::createFromAscii("1")),
115cdf0e10cSrcweir         parameters_count_(2)
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         parameters_[0] = join_param_.pData;
118cdf0e10cSrcweir         parameters_[1] = wait_time_.pData;
119cdf0e10cSrcweir         suCWD = getExecutablePath();
120cdf0e10cSrcweir         suExecutableFileURL = suCWD;
121cdf0e10cSrcweir         suExecutableFileURL += rtl::OUString::createFromAscii("/");
122cdf0e10cSrcweir         suExecutableFileURL += EXECUTABLE_NAME;
123cdf0e10cSrcweir     }
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     /*-------------------------------------
126cdf0e10cSrcweir         Start a process and join with this
127cdf0e10cSrcweir         process specify a timeout so that
128cdf0e10cSrcweir         osl_joinProcessWithTimeout returns
129cdf0e10cSrcweir         osl_Process_E_TimedOut
130cdf0e10cSrcweir      -------------------------------------*/
131cdf0e10cSrcweir 
132cdf0e10cSrcweir     void osl_joinProcessWithTimeout_timeout_failure()
133cdf0e10cSrcweir     {
134cdf0e10cSrcweir         oslProcess process;
135cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
136cdf0e10cSrcweir             suExecutableFileURL.pData,
137cdf0e10cSrcweir             parameters_,
138cdf0e10cSrcweir             parameters_count_,
139cdf0e10cSrcweir             osl_Process_NORMAL,
140cdf0e10cSrcweir             osl_getCurrentSecurity(),
141cdf0e10cSrcweir             suCWD.pData,
142cdf0e10cSrcweir             NULL,
143cdf0e10cSrcweir             0,
144cdf0e10cSrcweir             &process);
145cdf0e10cSrcweir 
146cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
147cdf0e10cSrcweir         (
148cdf0e10cSrcweir             "osl_createProcess failed",
149cdf0e10cSrcweir             osl_error == osl_Process_E_None
150cdf0e10cSrcweir         );
151cdf0e10cSrcweir 
152cdf0e10cSrcweir         TimeValue timeout;
153cdf0e10cSrcweir         timeout.Seconds = 1;
154cdf0e10cSrcweir         timeout.Nanosec = 0;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir         osl_error = osl_joinProcessWithTimeout(process, &timeout);
157cdf0e10cSrcweir 
158cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
159cdf0e10cSrcweir         (
160cdf0e10cSrcweir             "osl_joinProcessWithTimeout returned without timeout failure",
161cdf0e10cSrcweir             osl_Process_E_TimedOut == osl_error
162cdf0e10cSrcweir         );
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         osl_error = osl_terminateProcess(process);
165cdf0e10cSrcweir 
166cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
167cdf0e10cSrcweir         (
168cdf0e10cSrcweir             "osl_terminateProcess failed",
169cdf0e10cSrcweir             osl_error == osl_Process_E_None
170cdf0e10cSrcweir         );
171cdf0e10cSrcweir 
172cdf0e10cSrcweir         osl_freeProcessHandle(process);
173cdf0e10cSrcweir     }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir     /*-------------------------------------
176cdf0e10cSrcweir         Start a process and join with this
177cdf0e10cSrcweir         process specify a timeout so that
178cdf0e10cSrcweir         osl_joinProcessWithTimeout returns
179cdf0e10cSrcweir         osl_Process_E_None
180cdf0e10cSrcweir      -------------------------------------*/
181cdf0e10cSrcweir 
182cdf0e10cSrcweir     void osl_joinProcessWithTimeout_without_timeout_failure()
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         oslProcess process;
185cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
186cdf0e10cSrcweir             suExecutableFileURL.pData,
187cdf0e10cSrcweir             parameters_,
188cdf0e10cSrcweir             parameters_count_,
189cdf0e10cSrcweir             osl_Process_NORMAL,
190cdf0e10cSrcweir             osl_getCurrentSecurity(),
191cdf0e10cSrcweir             suCWD.pData,
192cdf0e10cSrcweir             NULL,
193cdf0e10cSrcweir             0,
194cdf0e10cSrcweir             &process);
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
197cdf0e10cSrcweir         (
198cdf0e10cSrcweir             "osl_createProcess failed",
199cdf0e10cSrcweir             osl_error == osl_Process_E_None
200cdf0e10cSrcweir         );
201cdf0e10cSrcweir 
202cdf0e10cSrcweir         TimeValue timeout;
203cdf0e10cSrcweir         timeout.Seconds = 10;
204cdf0e10cSrcweir         timeout.Nanosec = 0;
205cdf0e10cSrcweir 
206cdf0e10cSrcweir         osl_error = osl_joinProcessWithTimeout(process, &timeout);
207cdf0e10cSrcweir 
208cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
209cdf0e10cSrcweir         (
210cdf0e10cSrcweir             "osl_joinProcessWithTimeout returned with failure",
211cdf0e10cSrcweir             osl_Process_E_None == osl_error
212cdf0e10cSrcweir         );
213cdf0e10cSrcweir 
214cdf0e10cSrcweir         osl_freeProcessHandle(process);
215cdf0e10cSrcweir     }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir      /*-------------------------------------
218cdf0e10cSrcweir         Start a process and join with this
219cdf0e10cSrcweir         process specify an infinite timeout
220cdf0e10cSrcweir      -------------------------------------*/
221cdf0e10cSrcweir 
222cdf0e10cSrcweir     void osl_joinProcessWithTimeout_infinite()
223cdf0e10cSrcweir     {
224cdf0e10cSrcweir         oslProcess process;
225cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
226cdf0e10cSrcweir             suExecutableFileURL.pData,
227cdf0e10cSrcweir             parameters_,
228cdf0e10cSrcweir             parameters_count_,
229cdf0e10cSrcweir             osl_Process_NORMAL,
230cdf0e10cSrcweir             osl_getCurrentSecurity(),
231cdf0e10cSrcweir             suCWD.pData,
232cdf0e10cSrcweir             NULL,
233cdf0e10cSrcweir             0,
234cdf0e10cSrcweir             &process);
235cdf0e10cSrcweir 
236cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
237cdf0e10cSrcweir         (
238cdf0e10cSrcweir             "osl_createProcess failed",
239cdf0e10cSrcweir             osl_error == osl_Process_E_None
240cdf0e10cSrcweir         );
241cdf0e10cSrcweir 
242cdf0e10cSrcweir         osl_error = osl_joinProcessWithTimeout(process, NULL);
243cdf0e10cSrcweir 
244cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
245cdf0e10cSrcweir         (
246cdf0e10cSrcweir             "osl_joinProcessWithTimeout returned with failure",
247cdf0e10cSrcweir             osl_Process_E_None == osl_error
248cdf0e10cSrcweir         );
249cdf0e10cSrcweir 
250cdf0e10cSrcweir         osl_freeProcessHandle(process);
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir      /*-------------------------------------
254cdf0e10cSrcweir         Start a process and join with this
255cdf0e10cSrcweir         process using osl_joinProcess
256cdf0e10cSrcweir      -------------------------------------*/
257cdf0e10cSrcweir 
258cdf0e10cSrcweir      void osl_joinProcess()
259cdf0e10cSrcweir     {
260cdf0e10cSrcweir         oslProcess process;
261cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
262cdf0e10cSrcweir             suExecutableFileURL.pData,
263cdf0e10cSrcweir             parameters_,
264cdf0e10cSrcweir             parameters_count_,
265cdf0e10cSrcweir             osl_Process_NORMAL,
266cdf0e10cSrcweir             osl_getCurrentSecurity(),
267cdf0e10cSrcweir             suCWD.pData,
268cdf0e10cSrcweir             NULL,
269cdf0e10cSrcweir             0,
270cdf0e10cSrcweir             &process);
271cdf0e10cSrcweir 
272cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
273cdf0e10cSrcweir         (
274cdf0e10cSrcweir             "osl_createProcess failed",
275cdf0e10cSrcweir             osl_error == osl_Process_E_None
276cdf0e10cSrcweir         );
277cdf0e10cSrcweir 
278cdf0e10cSrcweir         osl_error = ::osl_joinProcess(process);
279cdf0e10cSrcweir 
280cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
281cdf0e10cSrcweir         (
282cdf0e10cSrcweir             "osl_joinProcess returned with failure",
283cdf0e10cSrcweir             osl_Process_E_None == osl_error
284cdf0e10cSrcweir         );
285cdf0e10cSrcweir 
286cdf0e10cSrcweir         osl_freeProcessHandle(process);
287cdf0e10cSrcweir     }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     CPPUNIT_TEST_SUITE(Test_osl_joinProcess);
290cdf0e10cSrcweir     CPPUNIT_TEST(osl_joinProcessWithTimeout_timeout_failure);
291cdf0e10cSrcweir     CPPUNIT_TEST(osl_joinProcessWithTimeout_without_timeout_failure);
292cdf0e10cSrcweir     CPPUNIT_TEST(osl_joinProcessWithTimeout_infinite);
293cdf0e10cSrcweir     CPPUNIT_TEST(osl_joinProcess);
294cdf0e10cSrcweir     CPPUNIT_TEST_SUITE_END();
295cdf0e10cSrcweir };
296cdf0e10cSrcweir 
297cdf0e10cSrcweir //#########################################################
298cdf0e10cSrcweir 
299cdf0e10cSrcweir typedef std::vector<std::string, rtl::Allocator<std::string> >  string_container_t;
300cdf0e10cSrcweir typedef string_container_t::const_iterator string_container_const_iter_t;
301cdf0e10cSrcweir typedef string_container_t::iterator       string_container_iter_t;
302cdf0e10cSrcweir 
303cdf0e10cSrcweir //#########################################################
304cdf0e10cSrcweir class exclude : public std::unary_function<std::string, bool>
305cdf0e10cSrcweir {
306cdf0e10cSrcweir public:
307cdf0e10cSrcweir     //------------------------------------------------
308cdf0e10cSrcweir     exclude(const string_container_t& exclude_list)
309cdf0e10cSrcweir     {
310cdf0e10cSrcweir         string_container_const_iter_t iter     = exclude_list.begin();
311cdf0e10cSrcweir         string_container_const_iter_t iter_end = exclude_list.end();
312cdf0e10cSrcweir         for (/**/; iter != iter_end; ++iter)
313cdf0e10cSrcweir             exclude_list_.push_back(env_var_name(*iter));
314cdf0e10cSrcweir     }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     //------------------------------------------------
317cdf0e10cSrcweir     bool operator() (const std::string& env_var) const
318cdf0e10cSrcweir     {
319cdf0e10cSrcweir         return (exclude_list_.end() !=
320cdf0e10cSrcweir                 std::find(
321cdf0e10cSrcweir                     exclude_list_.begin(),
322cdf0e10cSrcweir                     exclude_list_.end(),
323cdf0e10cSrcweir                     env_var_name(env_var)));
324cdf0e10cSrcweir     }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir private:
327cdf0e10cSrcweir     //-------------------------------------------------
328cdf0e10cSrcweir     // extract the name from an environment variable
329cdf0e10cSrcweir     // that is given in the form "NAME=VALUE"
330cdf0e10cSrcweir     std::string env_var_name(const std::string& env_var) const
331cdf0e10cSrcweir     {
332cdf0e10cSrcweir         std::string::size_type pos_equal_sign =
333cdf0e10cSrcweir             env_var.find_first_of("=");
334cdf0e10cSrcweir 
335cdf0e10cSrcweir         if (std::string::npos != pos_equal_sign)
336cdf0e10cSrcweir             return std::string(env_var, 0, pos_equal_sign);
337cdf0e10cSrcweir 
338cdf0e10cSrcweir         return std::string();
339cdf0e10cSrcweir     }
340cdf0e10cSrcweir 
341cdf0e10cSrcweir private:
342cdf0e10cSrcweir     string_container_t exclude_list_;
343cdf0e10cSrcweir };
344cdf0e10cSrcweir 
345cdf0e10cSrcweir #ifdef WNT
346cdf0e10cSrcweir     void read_parent_environment(string_container_t* env_container)
347cdf0e10cSrcweir     {
348cdf0e10cSrcweir         LPTSTR env = reinterpret_cast<LPTSTR>(GetEnvironmentStrings());
349cdf0e10cSrcweir         LPTSTR p   = env;
350cdf0e10cSrcweir 
351cdf0e10cSrcweir         while (size_t l = _tcslen(p))
352cdf0e10cSrcweir         {
353cdf0e10cSrcweir             env_container->push_back(std::string(p));
354cdf0e10cSrcweir             p += l + 1;
355cdf0e10cSrcweir         }
356cdf0e10cSrcweir         FreeEnvironmentStrings(env);
357cdf0e10cSrcweir     }
358cdf0e10cSrcweir #else
359cdf0e10cSrcweir     extern char** environ;
360cdf0e10cSrcweir     void read_parent_environment(string_container_t* env_container)
361cdf0e10cSrcweir     {
362cdf0e10cSrcweir         for (int i = 0; NULL != environ[i]; i++)
363cdf0e10cSrcweir             env_container->push_back(std::string(environ[i]));
364cdf0e10cSrcweir     }
365cdf0e10cSrcweir #endif
366cdf0e10cSrcweir 
367cdf0e10cSrcweir //#########################################################
368cdf0e10cSrcweir class Test_osl_executeProcess : public CppUnit::TestFixture
369cdf0e10cSrcweir {
370cdf0e10cSrcweir     const OUString env_param_;
371cdf0e10cSrcweir 
372cdf0e10cSrcweir     OUString     temp_file_path_;
373cdf0e10cSrcweir     rtl_uString* parameters_[2];
374cdf0e10cSrcweir     int          parameters_count_;
375cdf0e10cSrcweir     OUString	suCWD;
376cdf0e10cSrcweir     OUString	suExecutableFileURL;
377cdf0e10cSrcweir 
378cdf0e10cSrcweir public:
379cdf0e10cSrcweir 
380cdf0e10cSrcweir     //------------------------------------------------
381cdf0e10cSrcweir     // ctor
382cdf0e10cSrcweir     Test_osl_executeProcess() :
383cdf0e10cSrcweir         env_param_(OUString::createFromAscii("-env")),
384cdf0e10cSrcweir         parameters_count_(2)
385cdf0e10cSrcweir     {
386cdf0e10cSrcweir         parameters_[0] = env_param_.pData;
387cdf0e10cSrcweir         suCWD = getExecutablePath();
388cdf0e10cSrcweir         suExecutableFileURL = suCWD;
389cdf0e10cSrcweir         suExecutableFileURL += rtl::OUString::createFromAscii("/");
390cdf0e10cSrcweir         suExecutableFileURL += EXECUTABLE_NAME;
391cdf0e10cSrcweir     }
392cdf0e10cSrcweir 
393cdf0e10cSrcweir     //------------------------------------------------
394cdf0e10cSrcweir     virtual void setUp()
395cdf0e10cSrcweir     {
396cdf0e10cSrcweir         temp_file_path_ = create_temp_file();
397cdf0e10cSrcweir         parameters_[1]  = temp_file_path_.pData;
398cdf0e10cSrcweir     }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir     //------------------------------------------------
401cdf0e10cSrcweir     OUString create_temp_file()
402cdf0e10cSrcweir     {
403cdf0e10cSrcweir         OUString temp_file_url;
404cdf0e10cSrcweir         FileBase::RC rc = FileBase::createTempFile(0, 0, &temp_file_url);
405cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE("createTempFile failed", FileBase::E_None == rc);
406cdf0e10cSrcweir 
407cdf0e10cSrcweir         OUString temp_file_path;
408cdf0e10cSrcweir         rc = FileBase::getSystemPathFromFileURL(temp_file_url, temp_file_path);
409cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE("getSystemPathFromFileURL failed", FileBase::E_None == rc);
410cdf0e10cSrcweir 
411cdf0e10cSrcweir         return temp_file_path;
412cdf0e10cSrcweir     }
413cdf0e10cSrcweir 
414cdf0e10cSrcweir    //------------------------------------------------
415cdf0e10cSrcweir     void read_child_environment(string_container_t* env_container)
416cdf0e10cSrcweir     {
417cdf0e10cSrcweir         OString temp_file_name = OUStringToOString(OUString(
418cdf0e10cSrcweir             parameters_[1]), osl_getThreadTextEncoding());
419cdf0e10cSrcweir         std::ifstream file(temp_file_name.getStr());
420cdf0e10cSrcweir 
421cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
422cdf0e10cSrcweir         (
423cdf0e10cSrcweir             "I/O error, cannot open child environment file",
424cdf0e10cSrcweir             file.is_open()
425cdf0e10cSrcweir         );
426cdf0e10cSrcweir 
427cdf0e10cSrcweir         std::string line;
428cdf0e10cSrcweir         while (std::getline(file, line))
429cdf0e10cSrcweir             env_container->push_back(line);
430cdf0e10cSrcweir     }
431cdf0e10cSrcweir 
432cdf0e10cSrcweir     //------------------------------------------------
433cdf0e10cSrcweir     void dump_env(const string_container_t& env, OUString file_name)
434cdf0e10cSrcweir     {
435cdf0e10cSrcweir         OString fname = OUStringToOString(file_name, osl_getThreadTextEncoding());
436cdf0e10cSrcweir         std::ofstream file(fname.getStr());
437cdf0e10cSrcweir         std::ostream_iterator<std::string> oi(file, "\n");
438cdf0e10cSrcweir 		std::copy(env.begin(), env.end(), oi);
439cdf0e10cSrcweir     }
440cdf0e10cSrcweir 
441cdf0e10cSrcweir     //------------------------------------------------
442cdf0e10cSrcweir     // environment of the child process that was
443cdf0e10cSrcweir     // started. The child process writes his
444cdf0e10cSrcweir     // environment into a file
445cdf0e10cSrcweir     bool compare_environments()
446cdf0e10cSrcweir     {
447cdf0e10cSrcweir         string_container_t parent_env;
448cdf0e10cSrcweir         read_parent_environment(&parent_env);
449cdf0e10cSrcweir 
450cdf0e10cSrcweir         string_container_t child_env;
451cdf0e10cSrcweir 		read_child_environment(&child_env);
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 		return ((parent_env.size() == child_env.size()) &&
454cdf0e10cSrcweir 		        (std::equal(child_env.begin(), child_env.end(), parent_env.begin())));
455cdf0e10cSrcweir     }
456cdf0e10cSrcweir 
457cdf0e10cSrcweir     //------------------------------------------------
458cdf0e10cSrcweir     // compare the equal environment parts and the
459cdf0e10cSrcweir     // different part of the child environment
460cdf0e10cSrcweir     bool compare_merged_environments(const string_container_t& different_env_vars)
461cdf0e10cSrcweir     {
462cdf0e10cSrcweir         string_container_t parent_env;
463cdf0e10cSrcweir         read_parent_environment(&parent_env);
464cdf0e10cSrcweir 
465cdf0e10cSrcweir         //remove the environment variables that we have changed
466cdf0e10cSrcweir         //in the child environment from the read parent environment
467cdf0e10cSrcweir         parent_env.erase(
468cdf0e10cSrcweir             std::remove_if(parent_env.begin(), parent_env.end(), exclude(different_env_vars)),
469cdf0e10cSrcweir             parent_env.end());
470cdf0e10cSrcweir 
471cdf0e10cSrcweir         //read the child environment and exclude the variables that
472cdf0e10cSrcweir         //are different
473cdf0e10cSrcweir         string_container_t child_env;
474cdf0e10cSrcweir         read_child_environment(&child_env);
475cdf0e10cSrcweir 
476cdf0e10cSrcweir         //partition the child environment into the variables that
477cdf0e10cSrcweir         //are different to the parent environment (they come first)
478cdf0e10cSrcweir         //and the variables that should be equal between parent
479cdf0e10cSrcweir         //and child environment
480cdf0e10cSrcweir         string_container_iter_t iter_logical_end =
481cdf0e10cSrcweir             std::stable_partition(child_env.begin(), child_env.end(), exclude(different_env_vars));
482cdf0e10cSrcweir 
483cdf0e10cSrcweir         string_container_t different_child_env_vars(child_env.begin(), iter_logical_end);
484cdf0e10cSrcweir         child_env.erase(child_env.begin(), iter_logical_end);
485cdf0e10cSrcweir 
486cdf0e10cSrcweir         bool common_env_size_equals    = (parent_env.size() == child_env.size());
487cdf0e10cSrcweir         bool common_env_content_equals = std::equal(child_env.begin(), child_env.end(), parent_env.begin());
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 		bool different_env_size_equals    = (different_child_env_vars.size() == different_env_vars.size());
490cdf0e10cSrcweir 		bool different_env_content_equals =
491cdf0e10cSrcweir 		    std::equal(different_env_vars.begin(), different_env_vars.end(), different_child_env_vars.begin());
492cdf0e10cSrcweir 
493cdf0e10cSrcweir         return (common_env_size_equals && common_env_content_equals &&
494cdf0e10cSrcweir                 different_env_size_equals && different_env_content_equals);
495cdf0e10cSrcweir     }
496cdf0e10cSrcweir 
497cdf0e10cSrcweir     //------------------------------------------------
498cdf0e10cSrcweir     // test that parent and child process have the
499cdf0e10cSrcweir     // same environment when osl_executeProcess will
500cdf0e10cSrcweir     // be called with out setting new environment
501cdf0e10cSrcweir     // variables
502cdf0e10cSrcweir    void osl_execProc_parent_equals_child_environment()
503cdf0e10cSrcweir     {
504cdf0e10cSrcweir         oslProcess process;
505cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
506cdf0e10cSrcweir             suExecutableFileURL.pData,
507cdf0e10cSrcweir             parameters_,
508cdf0e10cSrcweir             parameters_count_,
509cdf0e10cSrcweir             osl_Process_NORMAL,
510cdf0e10cSrcweir             NULL,
511cdf0e10cSrcweir             suCWD.pData,
512cdf0e10cSrcweir             NULL,
513cdf0e10cSrcweir             0,
514cdf0e10cSrcweir             &process);
515cdf0e10cSrcweir 
516cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
517cdf0e10cSrcweir         (
518cdf0e10cSrcweir             "osl_createProcess failed",
519cdf0e10cSrcweir             osl_error == osl_Process_E_None
520cdf0e10cSrcweir         );
521cdf0e10cSrcweir 
522cdf0e10cSrcweir         osl_error = ::osl_joinProcess(process);
523cdf0e10cSrcweir 
524cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
525cdf0e10cSrcweir         (
526cdf0e10cSrcweir             "osl_joinProcess returned with failure",
527cdf0e10cSrcweir             osl_Process_E_None == osl_error
528cdf0e10cSrcweir         );
529cdf0e10cSrcweir 
530cdf0e10cSrcweir         osl_freeProcessHandle(process);
531cdf0e10cSrcweir 
532cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
533cdf0e10cSrcweir         (
534cdf0e10cSrcweir             "Parent an child environment not equal",
535cdf0e10cSrcweir             compare_environments()
536cdf0e10cSrcweir         );
537cdf0e10cSrcweir     }
538cdf0e10cSrcweir 
539cdf0e10cSrcweir     //------------------------------------------------
540cdf0e10cSrcweir     #define ENV1 "PAT=a:\\"
541cdf0e10cSrcweir     #define ENV2 "PATHb=b:\\"
542cdf0e10cSrcweir     #define ENV3 "Patha=c:\\"
543cdf0e10cSrcweir     #define ENV4 "Patha=d:\\"
544cdf0e10cSrcweir 
545cdf0e10cSrcweir     void osl_execProc_merged_child_environment()
546cdf0e10cSrcweir     {
547cdf0e10cSrcweir         rtl_uString* child_env[4];
548cdf0e10cSrcweir         OUString env1 = OUString::createFromAscii(ENV1);
549cdf0e10cSrcweir         OUString env2 = OUString::createFromAscii(ENV2);
550cdf0e10cSrcweir         OUString env3 = OUString::createFromAscii(ENV3);
551cdf0e10cSrcweir         OUString env4 = OUString::createFromAscii(ENV4);
552cdf0e10cSrcweir 
553cdf0e10cSrcweir         child_env[0] = env1.pData;
554cdf0e10cSrcweir         child_env[1] = env2.pData;
555cdf0e10cSrcweir         child_env[2] = env3.pData;
556cdf0e10cSrcweir         child_env[3] = env4.pData;
557cdf0e10cSrcweir 
558cdf0e10cSrcweir         oslProcess process;
559cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
560cdf0e10cSrcweir             suExecutableFileURL.pData,
561cdf0e10cSrcweir             parameters_,
562cdf0e10cSrcweir             parameters_count_,
563cdf0e10cSrcweir             osl_Process_NORMAL,
564cdf0e10cSrcweir             NULL,
565cdf0e10cSrcweir             suCWD.pData,
566cdf0e10cSrcweir             child_env,
567cdf0e10cSrcweir             sizeof(child_env)/sizeof(child_env[0]),
568cdf0e10cSrcweir             &process);
569cdf0e10cSrcweir 
570cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
571cdf0e10cSrcweir         (
572cdf0e10cSrcweir             "osl_createProcess failed",
573cdf0e10cSrcweir             osl_error == osl_Process_E_None
574cdf0e10cSrcweir         );
575cdf0e10cSrcweir 
576cdf0e10cSrcweir         osl_error = ::osl_joinProcess(process);
577cdf0e10cSrcweir 
578cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
579cdf0e10cSrcweir         (
580cdf0e10cSrcweir             "osl_joinProcess returned with failure",
581cdf0e10cSrcweir             osl_Process_E_None == osl_error
582cdf0e10cSrcweir         );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir         osl_freeProcessHandle(process);
585cdf0e10cSrcweir 
586cdf0e10cSrcweir         string_container_t different_child_env_vars;
587cdf0e10cSrcweir         different_child_env_vars.push_back(ENV1);
588cdf0e10cSrcweir         different_child_env_vars.push_back(ENV2);
589cdf0e10cSrcweir         different_child_env_vars.push_back(ENV4);
590cdf0e10cSrcweir 
591cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
592cdf0e10cSrcweir         (
593cdf0e10cSrcweir             "osl_execProc_merged_child_environment",
594cdf0e10cSrcweir             compare_merged_environments(different_child_env_vars)
595cdf0e10cSrcweir         );
596cdf0e10cSrcweir     }
597cdf0e10cSrcweir 
598cdf0e10cSrcweir     void osl_execProc_test_batch()
599cdf0e10cSrcweir     {
600cdf0e10cSrcweir         oslProcess process;
601cdf0e10cSrcweir         rtl::OUString suBatch = suCWD + rtl::OUString::createFromAscii("/") + rtl::OUString::createFromAscii("batch.bat");
602cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
603cdf0e10cSrcweir             suBatch.pData,
604cdf0e10cSrcweir             NULL,
605cdf0e10cSrcweir             0,
606cdf0e10cSrcweir             osl_Process_NORMAL,
607cdf0e10cSrcweir             NULL,
608cdf0e10cSrcweir             suCWD.pData,
609cdf0e10cSrcweir             NULL,
610cdf0e10cSrcweir             0,
611cdf0e10cSrcweir             &process);
612cdf0e10cSrcweir 
613cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
614cdf0e10cSrcweir         (
615cdf0e10cSrcweir             "osl_createProcess failed",
616cdf0e10cSrcweir             osl_error == osl_Process_E_None
617cdf0e10cSrcweir         );
618cdf0e10cSrcweir 
619cdf0e10cSrcweir         osl_error = ::osl_joinProcess(process);
620cdf0e10cSrcweir 
621cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
622cdf0e10cSrcweir         (
623cdf0e10cSrcweir             "osl_joinProcess returned with failure",
624cdf0e10cSrcweir             osl_Process_E_None == osl_error
625cdf0e10cSrcweir         );
626cdf0e10cSrcweir 
627cdf0e10cSrcweir         osl_freeProcessHandle(process);
628cdf0e10cSrcweir     }
629cdf0e10cSrcweir 
630cdf0e10cSrcweir     void osl_execProc_exe_name_in_argument_list()
631cdf0e10cSrcweir     {
632cdf0e10cSrcweir         rtl_uString* params[3];
633cdf0e10cSrcweir 
634cdf0e10cSrcweir         params[0] = suExecutableFileURL.pData;
635cdf0e10cSrcweir         params[1] = env_param_.pData;
636cdf0e10cSrcweir         params[2] = temp_file_path_.pData;
637cdf0e10cSrcweir         oslProcess process;
638cdf0e10cSrcweir         oslProcessError osl_error = osl_executeProcess(
639cdf0e10cSrcweir             NULL,
640cdf0e10cSrcweir             params,
641cdf0e10cSrcweir             3,
642cdf0e10cSrcweir             osl_Process_NORMAL,
643cdf0e10cSrcweir             NULL,
644cdf0e10cSrcweir             suCWD.pData,
645cdf0e10cSrcweir             NULL,
646cdf0e10cSrcweir             0,
647cdf0e10cSrcweir             &process);
648cdf0e10cSrcweir 
649cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
650cdf0e10cSrcweir         (
651cdf0e10cSrcweir             "osl_createProcess failed",
652cdf0e10cSrcweir             osl_error == osl_Process_E_None
653cdf0e10cSrcweir         );
654cdf0e10cSrcweir 
655cdf0e10cSrcweir         osl_error = ::osl_joinProcess(process);
656cdf0e10cSrcweir 
657cdf0e10cSrcweir         CPPUNIT_ASSERT_MESSAGE
658cdf0e10cSrcweir         (
659cdf0e10cSrcweir             "osl_joinProcess returned with failure",
660cdf0e10cSrcweir             osl_Process_E_None == osl_error
661cdf0e10cSrcweir         );
662cdf0e10cSrcweir 
663cdf0e10cSrcweir         osl_freeProcessHandle(process);
664cdf0e10cSrcweir     }
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     CPPUNIT_TEST_SUITE(Test_osl_executeProcess);
667cdf0e10cSrcweir     CPPUNIT_TEST(osl_execProc_parent_equals_child_environment);
668cdf0e10cSrcweir     CPPUNIT_TEST(osl_execProc_merged_child_environment);
669cdf0e10cSrcweir     CPPUNIT_TEST(osl_execProc_test_batch);
670cdf0e10cSrcweir     CPPUNIT_TEST(osl_execProc_exe_name_in_argument_list);
671cdf0e10cSrcweir     CPPUNIT_TEST_SUITE_END();
672cdf0e10cSrcweir };
673cdf0e10cSrcweir 
674cdf0e10cSrcweir //#####################################
675cdf0e10cSrcweir // register test suites
676cdf0e10cSrcweir //CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test_osl_joinProcess,    "Test_osl_joinProcess");
677cdf0e10cSrcweir CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test_osl_executeProcess, "Test_osl_executeProcess");
678cdf0e10cSrcweir 
679cdf0e10cSrcweir NOADDITIONAL;
680cdf0e10cSrcweir 
681