xref: /aoo4110/main/sal/qa/rtl/process/rtl_Process.cxx (revision b1cdbd2c)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sal.hxx"
26 
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sal/types.h>
31 
32 #include <testshl/simpleheader.hxx>
33 #include <rtl/ustring.hxx>
34 #include <rtl/string.hxx>
35 #include <rtl/process.h>
36 #include <osl/process.h>
37 #include <osl/module.hxx>
38 
39 #include "rtl_Process_Const.h"
40 
41 using namespace osl;
42 using namespace rtl;
43 
44 /** print a UNI_CODE String. And also print some comments of the string.
45 */
printUString(const::rtl::OUString & str,const sal_Char * msg=NULL)46 inline void printUString( const ::rtl::OUString & str, const sal_Char * msg = NULL )
47 {
48     if ( msg != NULL )
49     {
50     	t_print("#%s #printUString_u# ", msg );
51     }
52     rtl::OString aString;
53     aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US );
54     t_print("%s\n", (char *)aString.getStr( ) );
55 }
56 
57 // -----------------------------------------------------------------------------
getModulePath(void)58 inline ::rtl::OUString getModulePath( void )
59 {
60     ::rtl::OUString suDirPath;
61     ::osl::Module::getUrlFromAddress(
62         reinterpret_cast< oslGenericFunction >(getModulePath), suDirPath );
63 
64     printUString(suDirPath, "modulePath:");
65     suDirPath = suDirPath.copy( 0, suDirPath.lastIndexOf('/') );
66     suDirPath = suDirPath.copy( 0, suDirPath.lastIndexOf('/') + 1);
67     suDirPath += rtl::OUString::createFromAscii("bin");
68     return suDirPath;
69 }
70 
71 // -----------------------------------------------------------------------------
72 
73 namespace rtl_Process
74 {
75 class getAppCommandArg : public CppUnit::TestFixture
76 {
77 public:
78     // initialise your test code values here.
setUp()79     void setUp()
80     {
81     }
82 
tearDown()83     void tearDown()
84     {
85     }
86 
getAppCommandArg_001()87     void getAppCommandArg_001()
88     {
89 #if defined(WNT) || defined(OS2)
90 	const rtl::OUString EXECUTABLE_NAME = rtl::OUString::createFromAscii("child_process.exe");
91 #else
92 	const rtl::OUString EXECUTABLE_NAME = rtl::OUString::createFromAscii("child_process");
93 #endif
94         rtl::OUString suCWD = getModulePath();
95         // rtl::OUString suCWD2 = getExecutableDirectory();
96 
97         printUString(suCWD, "path to the current module");
98         // printUString(suCWD2, "suCWD2");
99 
100     	oslProcess hProcess = NULL;
101 
102         const int nParameterCount = 4;
103     	rtl_uString* pParameters[ nParameterCount ];
104 
105         pParameters[0] = suParam0.pData;
106         pParameters[1] = suParam1.pData;
107         pParameters[2] = suParam2.pData;
108         pParameters[3] = suParam3.pData;
109 
110         rtl::OUString suFileURL = suCWD;
111         suFileURL += rtl::OUString::createFromAscii("/");
112         suFileURL += EXECUTABLE_NAME;
113 
114         oslProcessError osl_error = osl_executeProcess(
115             suFileURL.pData,
116             pParameters,
117             nParameterCount,
118             osl_Process_WAIT,
119             0, /* osl_getCurrentSecurity() */
120             suCWD.pData,
121             NULL,
122             0,
123             &hProcess );
124 
125         CPPUNIT_ASSERT_MESSAGE
126         (
127             "osl_createProcess failed",
128             osl_error == osl_Process_E_None
129         );
130 	//we could get return value only after the process terminated
131         osl_joinProcess(hProcess);
132         // CPPUNIT_ASSERT_MESSAGE
133         // (
134         //     "osl_joinProcess returned with failure",
135         //     osl_Process_E_None == osl_error
136         // );
137 	oslProcessInfo* pInfo = new oslProcessInfo;
138 	//please pay attention to initial the Size to sizeof(oslProcessInfo), or else
139 	//you will get unknow error when call osl_getProcessInfo
140 	pInfo->Size = sizeof(oslProcessInfo);
141 	osl_error = osl_getProcessInfo( hProcess, osl_Process_EXITCODE, pInfo );
142 	CPPUNIT_ASSERT_MESSAGE
143         (
144             "osl_getProcessInfo returned with failure",
145             osl_Process_E_None == osl_error
146         );
147 
148 	t_print("the exit code is %d.\n", pInfo->Code );
149 	CPPUNIT_ASSERT_MESSAGE("rtl_getAppCommandArg or rtl_getAppCommandArgCount error.", pInfo->Code == 2);
150 	delete pInfo;
151     }
152 
153 
154     CPPUNIT_TEST_SUITE(getAppCommandArg);
155     CPPUNIT_TEST(getAppCommandArg_001);
156   //  CPPUNIT_TEST(getAppCommandArg_002);
157     CPPUNIT_TEST_SUITE_END();
158 }; // class getAppCommandArg
159 
160 /************************************************************************
161  * For diagnostics( from sal/test/testuuid.cxx )
162  ************************************************************************/
printUuid(sal_uInt8 * pNode)163 void printUuid( sal_uInt8 *pNode )
164 {
165     printf("# UUID is: ");
166     for( sal_Int32 i1 = 0 ; i1 < 4 ; i1++ )
167     {
168         for( sal_Int32 i2 = 0 ; i2 < 4 ; i2++ )
169         {
170             sal_uInt8 nValue = pNode[i1*4 +i2];
171             if (nValue < 16)
172             {
173                 printf( "0");
174             }
175             printf( "%02x" ,nValue );
176         }
177         if( i1 == 3 )
178             break;
179         printf( "-" );
180     }
181     printf("\n");
182 }
183 
184 /**************************************************************************
185  *  output UUID to a string
186  **************************************************************************/
printUuidtoBuffer(sal_uInt8 * pNode,sal_Char * pBuffer)187 void printUuidtoBuffer( sal_uInt8 *pNode, sal_Char * pBuffer )
188 {
189     sal_Int8 nPtr = 0;
190     for( sal_Int32 i1 = 0 ; i1 < 16 ; i1++ )
191     {
192         sal_uInt8 nValue = pNode[i1];
193         if (nValue < 16)
194         {
195              sprintf( (sal_Char *)(pBuffer + nPtr), "0");
196              nPtr++;
197         }
198         sprintf( (sal_Char *)(pBuffer + nPtr), "%02x", nValue );
199         nPtr += 2 ;
200     }
201 }
202 
203 class getGlobalProcessId : public CppUnit::TestFixture
204 {
205 public:
206     // initialise your test code values here.
setUp()207     void setUp()
208     {
209     }
210 
tearDown()211     void tearDown()
212     {
213     }
214     //gets a 16-byte fixed size identifier which is guaranteed not to change	during the current process.
getGlobalProcessId_001()215     void getGlobalProcessId_001()
216     {
217     	sal_uInt8 pTargetUUID1[16];
218     	sal_uInt8 pTargetUUID2[16];
219     	rtl_getGlobalProcessId( pTargetUUID1 );
220     	rtl_getGlobalProcessId( pTargetUUID2 );
221 	CPPUNIT_ASSERT_MESSAGE("getGlobalProcessId: got two same ProcessIds.", !memcmp( pTargetUUID1 , pTargetUUID2 , 16 ) );
222     }
223     //different processes different pids
getGlobalProcessId_002()224     void getGlobalProcessId_002()
225     {
226 #if defined(WNT) || defined(OS2)
227 	const rtl::OUString EXEC_NAME = rtl::OUString::createFromAscii("child_process_id.exe");
228 #else
229 	const rtl::OUString EXEC_NAME = rtl::OUString::createFromAscii("child_process_id");
230 #endif
231     	sal_uInt8 pTargetUUID1[16];
232     	rtl_getGlobalProcessId( pTargetUUID1 );
233     	printUuid( pTargetUUID1 );
234     	sal_Char pUUID1[32];
235       	printUuidtoBuffer( pTargetUUID1, pUUID1 );
236 	printf("# UUID to String is %s\n", pUUID1);
237 
238 	rtl::OUString suCWD = getModulePath();
239     	oslProcess hProcess = NULL;
240    	rtl::OUString suFileURL = suCWD;
241         suFileURL += rtl::OUString::createFromAscii("/");
242         suFileURL += EXEC_NAME;
243 	oslFileHandle* pChildOutputRead = new oslFileHandle();
244         oslProcessError osl_error = osl_executeProcess_WithRedirectedIO(
245             suFileURL.pData,
246             NULL,
247             0,
248             osl_Process_WAIT,
249             0,
250             suCWD.pData,
251             NULL,
252             0,
253             &hProcess,
254 	    NULL,
255 	    pChildOutputRead,
256 	    NULL);
257 
258         CPPUNIT_ASSERT_MESSAGE
259         (
260             "osl_createProcess failed",
261             osl_error == osl_Process_E_None
262         );
263 	//we could get return value only after the process terminated
264         osl_joinProcess(hProcess);
265 
266         sal_Char pUUID2[33];
267         pUUID2[32] = '\0';
268 	sal_uInt64 nRead = 0;
269 	osl_readFile( *pChildOutputRead, pUUID2, 32, &nRead );
270 	t_print("read buffer is %s, nRead is %d \n", pUUID2, nRead );
271 	OUString suUUID2 = OUString::createFromAscii( pUUID2 );
272 	CPPUNIT_ASSERT_MESSAGE("getGlobalProcessId: got two same ProcessIds.", suUUID2.equalsAsciiL( pUUID1, 32) == sal_False );
273     }
274 
275     CPPUNIT_TEST_SUITE(getGlobalProcessId);
276     CPPUNIT_TEST(getGlobalProcessId_001);
277     CPPUNIT_TEST(getGlobalProcessId_002);
278     CPPUNIT_TEST_SUITE_END();
279 
280 }; // class getGlobalProcessId
281 
282 } // namespace rtl_Process
283 
284 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_Process::getAppCommandArg, "rtl_Process");
285 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_Process::getGlobalProcessId, "rtl_Process");
286 
287 
288 // -----------------------------------------------------------------------------
289 
290 // this macro creates an empty function, which will called by the RegisterAllFunctions()
291 // to let the user the possibility to also register some functions by hand.
292 NOADDITIONAL;
293