xref: /aoo41x/main/sal/osl/os2/process_impl.cxx (revision 87d2adbc)
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 
25 #define INCL_DOS
26 #include <os2.h>
27 
28 #include "osl/process.h"
29 #include <osl/mutex.h>
30 
31 #ifndef INCLUDED_LIMITS_H
32 #include <limits.h>
33 #define INCLUDED_LIMITS_H
34 #endif
35 
36 #ifndef INCLUDED_PTHREAD_H
37 #include <pthread.h>
38 #define INCLUDED_PTHREAD_H
39 #endif
40 
41 #ifndef INCLUDED_STDLIB_H
42 #include <stdlib.h>
43 #define INCLUDED_STDLIB_H
44 #endif
45 
46 #ifndef INCLUDED_STRING_H
47 #include <string.h>
48 #define INCLUDED_STRING_H
49 #endif
50 #include "osl/diagnose.h"
51 #include <osl/file.h>
52 #include "osl/module.h"
53 #include "osl/thread.h"
54 #include "rtl/ustring.hxx"
55 
56 #ifndef _OSL_FILE_PATH_HELPER_H_
57 #include "file_path_helper.h"
58 #endif
59 
60 #ifndef _OSL_UUNXAPI_H_
61 #include "uunxapi.h"
62 #endif
63 
64 /***************************************
65   osl_bootstrap_getExecutableFile_Impl().
66 
67   @internal
68   @see rtl_bootstrap
69   @see #i37371#
70 
71  **************************************/
72 
73 extern "C" oslProcessError SAL_CALL osl_bootstrap_getExecutableFile_Impl (
74 	rtl_uString ** ppFileURL
75 ) SAL_THROW_EXTERN_C();
76 
77 
78 oslProcessError SAL_CALL osl_bootstrap_getExecutableFile_Impl (
79 	rtl_uString ** ppFileURL
80 ) SAL_THROW_EXTERN_C()
81 {
82     oslProcessError result = osl_Process_E_NotFound;
83     CHAR    szName[CCHMAXPATH];
84 	PPIB    ppib;
85 	PTIB    ptib;
86 	APIRET	rc;
87 
88 	rc = DosGetInfoBlocks(&ptib, &ppib);
89 	rc = DosQueryModuleName(ppib->pib_hmte, sizeof(szName), szName);
90 
91 	if (rc == 0)
92 	{
93 		rtl_uString * pAbsPath = 0;
94 
95         rtl_string2UString(
96 			&pAbsPath,
97 			szName, strlen(szName), osl_getThreadTextEncoding(),
98 			OSTRING_TO_OUSTRING_CVTFLAGS);
99 
100 		if (pAbsPath)
101 		{
102 			/* Convert from path to url. */
103 			if (osl_getFileURLFromSystemPath (pAbsPath, ppFileURL) == osl_File_E_None)
104 			{
105 				/* Success. */
106 				result = osl_Process_E_None;
107 			}
108 			rtl_uString_release (pAbsPath);
109 		}
110 	}
111 
112 	return (result);
113 }
114 
115 /***************************************
116  CommandArgs_Impl.
117  **************************************/
118 struct CommandArgs_Impl
119 {
120 	oslMutex		m_mutex;
121 	sal_uInt32      m_nCount;
122 	rtl_uString **  m_ppArgs;
123 };
124 
125 static struct CommandArgs_Impl g_command_args =
126 {
127 	osl_createMutex(),
128 	0,
129 	0
130 };
131 
132 /***************************************
133   osl_getExecutableFile().
134  **************************************/
135 oslProcessError SAL_CALL osl_getExecutableFile (rtl_uString ** ppustrFile)
136 {
137 	oslProcessError result = osl_Process_E_NotFound;
138 
139 	osl_acquireMutex(g_command_args.m_mutex);
140     OSL_ASSERT(g_command_args.m_nCount > 0);
141 	if (g_command_args.m_nCount > 0)
142 	{
143 		/* CommandArgs set. Obtain argv[0]. */
144 		rtl_uString_assign (ppustrFile, g_command_args.m_ppArgs[0]);
145 		result = osl_Process_E_None;
146 	}
147 	osl_releaseMutex(g_command_args.m_mutex);
148 
149 	return (result);
150 }
151 
152 /***************************************
153  osl_getCommandArgCount().
154  **************************************/
155 sal_uInt32 SAL_CALL osl_getCommandArgCount (void)
156 {
157 	sal_uInt32 result = 0;
158 
159 	osl_acquireMutex(g_command_args.m_mutex);
160     OSL_ASSERT(g_command_args.m_nCount > 0);
161 	if (g_command_args.m_nCount > 0)
162 		result = g_command_args.m_nCount - 1;
163 	osl_releaseMutex(g_command_args.m_mutex);
164 
165 	return (result);
166 }
167 
168 /***************************************
169  osl_getCommandArg().
170  **************************************/
171 oslProcessError SAL_CALL osl_getCommandArg (sal_uInt32 nArg, rtl_uString ** strCommandArg)
172 {
173 	oslProcessError result = osl_Process_E_NotFound;
174 
175 	osl_acquireMutex(g_command_args.m_mutex);
176     OSL_ASSERT(g_command_args.m_nCount > 0);
177 	if (g_command_args.m_nCount > (nArg + 1))
178 	{
179 		rtl_uString_assign (strCommandArg, g_command_args.m_ppArgs[nArg + 1]);
180 		result = osl_Process_E_None;
181 	}
182 	osl_releaseMutex(g_command_args.m_mutex);
183 
184 	return (result);
185 }
186 
187 /***************************************
188  osl_setCommandArgs().
189  **************************************/
190 void SAL_CALL osl_setCommandArgs (int argc, char ** argv)
191 {
192     OSL_ASSERT(argc > 0);
193 	osl_acquireMutex(g_command_args.m_mutex);
194 	OSL_ENSURE (g_command_args.m_nCount == 0, "osl_setCommandArgs(): CommandArgs already set.");
195 	if (g_command_args.m_nCount == 0)
196 	{
197 		rtl_uString** ppArgs = (rtl_uString**)rtl_allocateZeroMemory (argc * sizeof(rtl_uString*));
198 		if (ppArgs != 0)
199 		{
200 			rtl_TextEncoding encoding = osl_getThreadTextEncoding();
201 			for (int i = 0; i < argc; i++)
202 			{
203 				rtl_string2UString (
204 					&(ppArgs[i]),
205 					argv[i], rtl_str_getLength (argv[i]), encoding,
206 					OSTRING_TO_OUSTRING_CVTFLAGS);
207 			}
208 			if (ppArgs[0] != 0)
209 			{
210 				/* see @ osl_getExecutableFile(). */
211 				if (rtl_ustr_indexOfChar (rtl_uString_getStr(ppArgs[0]), sal_Unicode('/')) == -1)
212 				{
213 					const rtl::OUString PATH (RTL_CONSTASCII_USTRINGPARAM("PATH"));
214 
215 					rtl_uString * pSearchPath = 0;
216 					osl_getEnvironment (PATH.pData, &pSearchPath);
217 					if (pSearchPath)
218 					{
219 						rtl_uString * pSearchResult = 0;
220 						osl_searchPath (ppArgs[0], pSearchPath, &pSearchResult);
221 						if (pSearchResult)
222 						{
223 							rtl_uString_assign (&(ppArgs[0]), pSearchResult);
224 							rtl_uString_release (pSearchResult);
225 						}
226 						rtl_uString_release (pSearchPath);
227 					}
228 				}
229 
230 				rtl_uString * pArg0 = 0;
231 				if (realpath_u (ppArgs[0], &pArg0))
232 				{
233 					osl_getFileURLFromSystemPath (pArg0, &(ppArgs[0]));
234 					rtl_uString_release (pArg0);
235 				}
236 			}
237 			g_command_args.m_nCount = argc;
238 			g_command_args.m_ppArgs = ppArgs;
239 		}
240 	}
241 	osl_releaseMutex(g_command_args.m_mutex);
242 
243 }
244 
245 /***************************************
246  osl_getEnvironment().
247  **************************************/
248 oslProcessError SAL_CALL osl_getEnvironment(rtl_uString* pustrEnvVar, rtl_uString** ppustrValue)
249 {
250 	oslProcessError  result   = osl_Process_E_NotFound;
251 	rtl_TextEncoding encoding = osl_getThreadTextEncoding();
252 	rtl_String* pstr_env_var  = 0;
253 
254 	OSL_PRECOND(pustrEnvVar, "osl_getEnvironment(): Invalid parameter");
255 	OSL_PRECOND(ppustrValue, "osl_getEnvironment(): Invalid parameter");
256 
257 	rtl_uString2String(
258 		&pstr_env_var,
259 		rtl_uString_getStr(pustrEnvVar), rtl_uString_getLength(pustrEnvVar), encoding,
260 		OUSTRING_TO_OSTRING_CVTFLAGS);
261 	if (pstr_env_var != 0)
262 	{
263 		const char* p_env_var = getenv (rtl_string_getStr (pstr_env_var));
264 		if (p_env_var != 0)
265 		{
266 			rtl_string2UString(
267 				ppustrValue,
268 				p_env_var, strlen(p_env_var), encoding,
269 				OSTRING_TO_OUSTRING_CVTFLAGS);
270 			OSL_ASSERT(*ppustrValue != NULL);
271 
272 			result = osl_Process_E_None;
273 		}
274 		rtl_string_release(pstr_env_var);
275 	}
276 
277 	return (result);
278 }
279 
280 /***************************************
281  osl_setEnvironment().
282  **************************************/
283 oslProcessError SAL_CALL osl_setEnvironment(rtl_uString* pustrEnvVar, rtl_uString* pustrValue)
284 {
285 	oslProcessError  result   = osl_Process_E_Unknown;
286 	rtl_TextEncoding encoding = osl_getThreadTextEncoding();
287 	rtl_String* pstr_env_var  = 0;
288 	rtl_String* pstr_val  = 0;
289 
290 	OSL_PRECOND(pustrEnvVar, "osl_setEnvironment(): Invalid parameter");
291 	OSL_PRECOND(pustrValue, "osl_setEnvironment(): Invalid parameter");
292 
293 	rtl_uString2String(
294 		&pstr_env_var,
295 		rtl_uString_getStr(pustrEnvVar), rtl_uString_getLength(pustrEnvVar), encoding,
296 		OUSTRING_TO_OSTRING_CVTFLAGS);
297 
298 	rtl_uString2String(
299 		&pstr_val,
300 		rtl_uString_getStr(pustrValue), rtl_uString_getLength(pustrValue), encoding,
301 		OUSTRING_TO_OSTRING_CVTFLAGS);
302 
303 	if (pstr_env_var != 0 && pstr_val != 0)
304 	{
305 		//Can't determine if OS/2 EMX has a working setenv or not, so use putenv,
306 		//feel free to use setenv here if its available and works
307 		rtl_String * pBuffer = NULL;
308 
309 		sal_Int32 nCapacity = rtl_stringbuffer_newFromStringBuffer( &pBuffer,
310 			rtl_string_getLength(pstr_env_var) + rtl_string_getLength(pstr_val) + 1,
311 			pstr_env_var );
312 		rtl_stringbuffer_insert( &pBuffer, &nCapacity, pBuffer->length, "=", 1);
313 		rtl_stringbuffer_insert( &pBuffer, &nCapacity, pBuffer->length,
314 			rtl_string_getStr(pstr_val), rtl_string_getLength(pstr_val) );
315 
316 		rtl_string_acquire(pBuffer); // argument to putenv must leak on success
317 
318 		if (putenv(rtl_string_getStr(pBuffer)) == 0)
319 			result = osl_Process_E_None;
320 		else
321 			rtl_string_release(pBuffer);
322 	}
323 
324 	if (pstr_val)
325 		rtl_string_release(pstr_val);
326 
327 	if (pstr_env_var != 0)
328 		rtl_string_release(pstr_env_var);
329 
330 	return (result);
331 }
332 
333 /***************************************
334  osl_clearEnvironment().
335  **************************************/
336 oslProcessError SAL_CALL osl_clearEnvironment(rtl_uString* pustrEnvVar)
337 {
338 	oslProcessError  result   = osl_Process_E_Unknown;
339 	rtl_TextEncoding encoding = osl_getThreadTextEncoding();
340 	rtl_String* pstr_env_var  = 0;
341 
342 	OSL_PRECOND(pustrEnvVar, "osl_setEnvironment(): Invalid parameter");
343 
344 	rtl_uString2String(
345 		&pstr_env_var,
346 		rtl_uString_getStr(pustrEnvVar), rtl_uString_getLength(pustrEnvVar), encoding,
347 		OUSTRING_TO_OSTRING_CVTFLAGS);
348 
349 	if (pstr_env_var)
350 	{
351 		//Can't determine if OS/2 EMX has a working unsetenv or not, so use putenv,
352 		//feel free to use unsetenv here if its available and works
353 		rtl_String * pBuffer = NULL;
354 
355 		sal_Int32 nCapacity = rtl_stringbuffer_newFromStringBuffer( &pBuffer,
356 			rtl_string_getLength(pstr_env_var) + 1, pstr_env_var );
357 		rtl_stringbuffer_insert( &pBuffer, &nCapacity, pBuffer->length, "=", 1);
358 
359 		rtl_string_acquire(pBuffer); // argument to putenv must leak on success
360 
361 		if (putenv(rtl_string_getStr(pBuffer)) == 0)
362 			result = osl_Process_E_None;
363 		else
364 			rtl_string_release(pBuffer);
365 
366 		rtl_string_release(pstr_env_var);
367 	}
368 
369 	return (result);
370 }
371 
372 /***************************************
373  osl_getProcessWorkingDir().
374  **************************************/
375 oslProcessError SAL_CALL osl_getProcessWorkingDir(rtl_uString **ppustrWorkingDir)
376 {
377     oslProcessError result = osl_Process_E_Unknown;
378 	char buffer[PATH_MAX];
379 
380 	OSL_PRECOND(ppustrWorkingDir, "osl_getProcessWorkingDir(): Invalid parameter");
381 
382     if (getcwd (buffer, sizeof(buffer)) != 0)
383     {
384         rtl_uString* ustrTmp = 0;
385 
386         rtl_string2UString(
387 			&ustrTmp,
388 			buffer, strlen(buffer), osl_getThreadTextEncoding(),
389 			OSTRING_TO_OUSTRING_CVTFLAGS);
390         if (ustrTmp != 0)
391         {
392 			if (osl_getFileURLFromSystemPath (ustrTmp, ppustrWorkingDir) == osl_File_E_None)
393 				result = osl_Process_E_None;
394 			rtl_uString_release (ustrTmp);
395 		}
396 	}
397 
398     return (result);
399 }
400 
401 /******************************************************************************
402  *
403  *              new functions to set/return the current process locale
404  *
405  *****************************************************************************/
406 
407 struct ProcessLocale_Impl
408 {
409 	oslMutex		m_mutex;
410 	rtl_Locale *    m_pLocale;
411 };
412 
413 static struct ProcessLocale_Impl g_process_locale =
414 {
415 	osl_createMutex(),
416 	0
417 };
418 
419 extern "C" void _imp_getProcessLocale( rtl_Locale ** );
420 extern "C" int  _imp_setProcessLocale( rtl_Locale * );
421 
422 /**********************************************
423  osl_getProcessLocale().
424  *********************************************/
425 oslProcessError SAL_CALL osl_getProcessLocale( rtl_Locale ** ppLocale )
426 {
427     OSL_PRECOND(ppLocale, "osl_getProcessLocale(): Invalid parameter.");
428 
429     osl_acquireMutex(g_process_locale.m_mutex);
430 
431     if (g_process_locale.m_pLocale == 0)
432         _imp_getProcessLocale (&(g_process_locale.m_pLocale));
433     *ppLocale = g_process_locale.m_pLocale;
434 
435     osl_releaseMutex(g_process_locale.m_mutex);
436 
437     return (osl_Process_E_None);
438 }
439 
440 /**********************************************
441  osl_setProcessLocale().
442  *********************************************/
443 oslProcessError SAL_CALL osl_setProcessLocale( rtl_Locale * pLocale )
444 {
445     oslProcessError result = osl_Process_E_Unknown;
446 
447     OSL_PRECOND(pLocale, "osl_setProcessLocale(): Invalid parameter.");
448 
449     osl_acquireMutex(g_process_locale.m_mutex);
450     if (_imp_setProcessLocale (pLocale) == 0)
451     {
452         g_process_locale.m_pLocale = pLocale;
453         result = osl_Process_E_None;
454     }
455     osl_releaseMutex(g_process_locale.m_mutex);
456 
457     return (result);
458 }
459 
460