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