1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sal.hxx"
31 #include "osl/process.h"
33 #ifndef INCLUDED_LIMITS_H
35 #define INCLUDED_LIMITS_H
38 #ifndef INCLUDED_PTHREAD_H
40 #define INCLUDED_PTHREAD_H
43 #ifndef INCLUDED_STDLIB_H
45 #define INCLUDED_STDLIB_H
48 #ifndef INCLUDED_STRING_H
50 #define INCLUDED_STRING_H
52 #include "osl/diagnose.h"
54 #include "osl/module.h"
55 #include "osl/thread.h"
56 #include "rtl/ustring.hxx"
57 #include "rtl/strbuf.h"
59 #ifndef _OSL_FILE_PATH_HELPER_H_
60 #include "file_path_helper.h"
63 #ifndef _OSL_UUNXAPI_H_
67 /***************************************
68 osl_bootstrap_getExecutableFile_Impl().
74 **************************************/
76 extern "C" oslProcessError SAL_CALL
osl_bootstrap_getExecutableFile_Impl (
77 rtl_uString
** ppFileURL
78 ) SAL_THROW_EXTERN_C();
82 #include <mach-o/dyld.h>
84 oslProcessError SAL_CALL
osl_bootstrap_getExecutableFile_Impl (
85 rtl_uString
** ppFileURL
86 ) SAL_THROW_EXTERN_C()
88 oslProcessError result
= osl_Process_E_NotFound
;
90 char buffer
[PATH_MAX
];
91 size_t buflen
= sizeof(buffer
);
93 #if __GNUC__ >= 4 && defined(MACOSX)
94 if (_NSGetExecutablePath (buffer
, (uint32_t*)&buflen
) == 0)
96 if (_NSGetExecutablePath (buffer
, &buflen
) == 0)
99 /* Determine absolute path. */
100 char abspath
[PATH_MAX
];
101 if (realpath (buffer
, abspath
) != 0)
103 /* Convert from utf8 to unicode. */
104 rtl_uString
* pAbsPath
= 0;
107 abspath
, rtl_str_getLength (abspath
),
108 RTL_TEXTENCODING_UTF8
,
109 OSTRING_TO_OUSTRING_CVTFLAGS
);
113 /* Convert from path to url. */
114 if (osl_getFileURLFromSystemPath (pAbsPath
, ppFileURL
) == osl_File_E_None
)
117 result
= osl_Process_E_None
;
119 rtl_uString_release (pAbsPath
);
127 #elif !defined(NO_DL_FUNCTIONS)
130 oslProcessError SAL_CALL
osl_bootstrap_getExecutableFile_Impl (
131 rtl_uString
** ppFileURL
132 ) SAL_THROW_EXTERN_C()
134 oslProcessError result
= osl_Process_E_NotFound
;
136 /* Determine address of "main()" function. */
137 void * addr
= dlsym (RTLD_DEFAULT
, "main");
140 /* Determine module URL. */
141 if (osl_getModuleURLFromAddress (addr
, ppFileURL
))
144 result
= osl_Process_E_None
;
151 #else /* NO_DL_FUNCTIONS */
153 oslProcessError SAL_CALL
osl_bootstrap_getExecutableFile_Impl (
154 rtl_uString
** ppFileURL
155 ) SAL_THROW_EXTERN_C()
157 /* Fallback to ordinary osl_getExecutableFile(). */
158 return osl_getExecutableFile (ppFileURL
);
161 #endif /* NO_DL_FUNCTIONS */
163 /***************************************
165 **************************************/
166 struct CommandArgs_Impl
168 pthread_mutex_t m_mutex
;
170 rtl_uString
** m_ppArgs
;
173 static struct CommandArgs_Impl g_command_args
=
175 PTHREAD_MUTEX_INITIALIZER
,
180 /***************************************
181 osl_getExecutableFile().
182 **************************************/
183 oslProcessError SAL_CALL
osl_getExecutableFile (rtl_uString
** ppustrFile
)
185 oslProcessError result
= osl_Process_E_NotFound
;
187 pthread_mutex_lock (&(g_command_args
.m_mutex
));
188 OSL_ASSERT(g_command_args
.m_nCount
> 0);
189 if (g_command_args
.m_nCount
> 0)
191 /* CommandArgs set. Obtain argv[0]. */
192 rtl_uString_assign (ppustrFile
, g_command_args
.m_ppArgs
[0]);
193 result
= osl_Process_E_None
;
195 pthread_mutex_unlock (&(g_command_args
.m_mutex
));
200 /***************************************
201 osl_getCommandArgCount().
202 **************************************/
203 sal_uInt32 SAL_CALL
osl_getCommandArgCount (void)
205 sal_uInt32 result
= 0;
207 pthread_mutex_lock (&(g_command_args
.m_mutex
));
208 OSL_ASSERT(g_command_args
.m_nCount
> 0);
209 if (g_command_args
.m_nCount
> 0)
210 result
= g_command_args
.m_nCount
- 1;
211 pthread_mutex_unlock (&(g_command_args
.m_mutex
));
216 /***************************************
218 **************************************/
219 oslProcessError SAL_CALL
osl_getCommandArg (sal_uInt32 nArg
, rtl_uString
** strCommandArg
)
221 oslProcessError result
= osl_Process_E_NotFound
;
223 pthread_mutex_lock (&(g_command_args
.m_mutex
));
224 OSL_ASSERT(g_command_args
.m_nCount
> 0);
225 if (g_command_args
.m_nCount
> (nArg
+ 1))
227 rtl_uString_assign (strCommandArg
, g_command_args
.m_ppArgs
[nArg
+ 1]);
228 result
= osl_Process_E_None
;
230 pthread_mutex_unlock (&(g_command_args
.m_mutex
));
235 /***************************************
236 osl_setCommandArgs().
237 **************************************/
238 void SAL_CALL
osl_setCommandArgs (int argc
, char ** argv
)
240 OSL_ASSERT(argc
> 0);
241 pthread_mutex_lock (&(g_command_args
.m_mutex
));
242 OSL_ENSURE (g_command_args
.m_nCount
== 0, "osl_setCommandArgs(): CommandArgs already set.");
243 if (g_command_args
.m_nCount
== 0)
245 rtl_uString
** ppArgs
= (rtl_uString
**)rtl_allocateZeroMemory (argc
* sizeof(rtl_uString
*));
248 rtl_TextEncoding encoding
= osl_getThreadTextEncoding();
249 for (int i
= 0; i
< argc
; i
++)
253 argv
[i
], rtl_str_getLength (argv
[i
]), encoding
,
254 OSTRING_TO_OUSTRING_CVTFLAGS
);
258 /* see @ osl_getExecutableFile(). */
259 if (rtl_ustr_indexOfChar (rtl_uString_getStr(ppArgs
[0]), sal_Unicode('/')) == -1)
261 const rtl::OUString
PATH (RTL_CONSTASCII_USTRINGPARAM("PATH"));
263 rtl_uString
* pSearchPath
= 0;
264 osl_getEnvironment (PATH
.pData
, &pSearchPath
);
267 rtl_uString
* pSearchResult
= 0;
268 osl_searchPath (ppArgs
[0], pSearchPath
, &pSearchResult
);
271 rtl_uString_assign (&(ppArgs
[0]), pSearchResult
);
272 rtl_uString_release (pSearchResult
);
274 rtl_uString_release (pSearchPath
);
278 rtl_uString
* pArg0
= 0;
279 if (realpath_u (ppArgs
[0], &pArg0
))
281 osl_getFileURLFromSystemPath (pArg0
, &(ppArgs
[0]));
282 rtl_uString_release (pArg0
);
285 g_command_args
.m_nCount
= argc
;
286 g_command_args
.m_ppArgs
= ppArgs
;
289 pthread_mutex_unlock (&(g_command_args
.m_mutex
));
292 /***************************************
293 osl_getEnvironment().
294 **************************************/
295 oslProcessError SAL_CALL
osl_getEnvironment(rtl_uString
* pustrEnvVar
, rtl_uString
** ppustrValue
)
297 oslProcessError result
= osl_Process_E_NotFound
;
298 rtl_TextEncoding encoding
= osl_getThreadTextEncoding();
299 rtl_String
* pstr_env_var
= 0;
301 OSL_PRECOND(pustrEnvVar
, "osl_getEnvironment(): Invalid parameter");
302 OSL_PRECOND(ppustrValue
, "osl_getEnvironment(): Invalid parameter");
306 rtl_uString_getStr(pustrEnvVar
), rtl_uString_getLength(pustrEnvVar
), encoding
,
307 OUSTRING_TO_OSTRING_CVTFLAGS
);
308 if (pstr_env_var
!= 0)
310 const char* p_env_var
= getenv (rtl_string_getStr (pstr_env_var
));
315 p_env_var
, strlen(p_env_var
), encoding
,
316 OSTRING_TO_OUSTRING_CVTFLAGS
);
317 OSL_ASSERT(*ppustrValue
!= NULL
);
319 result
= osl_Process_E_None
;
321 rtl_string_release(pstr_env_var
);
327 /***************************************
328 osl_setEnvironment().
329 **************************************/
330 oslProcessError SAL_CALL
osl_setEnvironment(rtl_uString
* pustrEnvVar
, rtl_uString
* pustrValue
)
332 oslProcessError result
= osl_Process_E_Unknown
;
333 rtl_TextEncoding encoding
= osl_getThreadTextEncoding();
334 rtl_String
* pstr_env_var
= 0;
335 rtl_String
* pstr_val
= 0;
337 OSL_PRECOND(pustrEnvVar
, "osl_setEnvironment(): Invalid parameter");
338 OSL_PRECOND(pustrValue
, "osl_setEnvironment(): Invalid parameter");
342 rtl_uString_getStr(pustrEnvVar
), rtl_uString_getLength(pustrEnvVar
), encoding
,
343 OUSTRING_TO_OSTRING_CVTFLAGS
);
347 rtl_uString_getStr(pustrValue
), rtl_uString_getLength(pustrValue
), encoding
,
348 OUSTRING_TO_OSTRING_CVTFLAGS
);
350 if (pstr_env_var
!= 0 && pstr_val
!= 0)
352 #if defined (SOLARIS)
353 rtl_String
* pBuffer
= NULL
;
355 sal_Int32 nCapacity
= rtl_stringbuffer_newFromStringBuffer( &pBuffer
,
356 rtl_string_getLength(pstr_env_var
) + rtl_string_getLength(pstr_val
) + 1,
358 rtl_stringbuffer_insert( &pBuffer
, &nCapacity
, pBuffer
->length
, "=", 1);
359 rtl_stringbuffer_insert( &pBuffer
, &nCapacity
, pBuffer
->length
,
360 rtl_string_getStr(pstr_val
), rtl_string_getLength(pstr_val
) );
362 rtl_string_acquire(pBuffer
); // argument to putenv must leak on success
364 if (putenv(rtl_string_getStr(pBuffer
)) == 0)
365 result
= osl_Process_E_None
;
367 rtl_string_release(pBuffer
);
369 if (setenv(rtl_string_getStr(pstr_env_var
), rtl_string_getStr(pstr_val
), 1) == 0)
370 result
= osl_Process_E_None
;
375 rtl_string_release(pstr_val
);
377 if (pstr_env_var
!= 0)
378 rtl_string_release(pstr_env_var
);
383 /***************************************
384 osl_clearEnvironment().
385 **************************************/
386 oslProcessError SAL_CALL
osl_clearEnvironment(rtl_uString
* pustrEnvVar
)
388 oslProcessError result
= osl_Process_E_Unknown
;
389 rtl_TextEncoding encoding
= osl_getThreadTextEncoding();
390 rtl_String
* pstr_env_var
= 0;
392 OSL_PRECOND(pustrEnvVar
, "osl_setEnvironment(): Invalid parameter");
396 rtl_uString_getStr(pustrEnvVar
), rtl_uString_getLength(pustrEnvVar
), encoding
,
397 OUSTRING_TO_OSTRING_CVTFLAGS
);
401 #if defined (SOLARIS)
402 rtl_String
* pBuffer
= NULL
;
404 sal_Int32 nCapacity
= rtl_stringbuffer_newFromStringBuffer( &pBuffer
,
405 rtl_string_getLength(pstr_env_var
) + 1, pstr_env_var
);
406 rtl_stringbuffer_insert( &pBuffer
, &nCapacity
, pBuffer
->length
, "=", 1);
408 rtl_string_acquire(pBuffer
); // argument to putenv must leak on success
410 if (putenv(rtl_string_getStr(pBuffer
)) == 0)
411 result
= osl_Process_E_None
;
413 rtl_string_release(pBuffer
);
414 #elif (defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
415 //MacOSX baseline is 10.4, which has an old-school void return
417 //See: http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/10.4/man3/unsetenv.3.html?useVersion=10.4
418 unsetenv(rtl_string_getStr(pstr_env_var
));
419 result
= osl_Process_E_None
;
421 if (unsetenv(rtl_string_getStr(pstr_env_var
)) == 0)
422 result
= osl_Process_E_None
;
424 rtl_string_release(pstr_env_var
);
431 /***************************************
432 osl_getProcessWorkingDir().
433 **************************************/
434 oslProcessError SAL_CALL
osl_getProcessWorkingDir(rtl_uString
**ppustrWorkingDir
)
436 oslProcessError result
= osl_Process_E_Unknown
;
437 char buffer
[PATH_MAX
];
439 OSL_PRECOND(ppustrWorkingDir
, "osl_getProcessWorkingDir(): Invalid parameter");
441 if (getcwd (buffer
, sizeof(buffer
)) != 0)
443 rtl_uString
* ustrTmp
= 0;
447 buffer
, strlen(buffer
), osl_getThreadTextEncoding(),
448 OSTRING_TO_OUSTRING_CVTFLAGS
);
451 if (osl_getFileURLFromSystemPath (ustrTmp
, ppustrWorkingDir
) == osl_File_E_None
)
452 result
= osl_Process_E_None
;
453 rtl_uString_release (ustrTmp
);
460 /******************************************************************************
462 * new functions to set/return the current process locale
464 *****************************************************************************/
466 struct ProcessLocale_Impl
468 pthread_mutex_t m_mutex
;
469 rtl_Locale
* m_pLocale
;
472 static struct ProcessLocale_Impl g_process_locale
=
474 PTHREAD_MUTEX_INITIALIZER
,
478 extern "C" void _imp_getProcessLocale( rtl_Locale
** );
479 extern "C" int _imp_setProcessLocale( rtl_Locale
* );
481 /**********************************************
482 osl_getProcessLocale().
483 *********************************************/
484 oslProcessError SAL_CALL
osl_getProcessLocale( rtl_Locale
** ppLocale
)
486 oslProcessError result
= osl_Process_E_Unknown
;
487 OSL_PRECOND(ppLocale
, "osl_getProcessLocale(): Invalid parameter.");
490 pthread_mutex_lock(&(g_process_locale
.m_mutex
));
492 if (g_process_locale
.m_pLocale
== 0)
493 _imp_getProcessLocale (&(g_process_locale
.m_pLocale
));
494 *ppLocale
= g_process_locale
.m_pLocale
;
495 result
= osl_Process_E_None
;
497 pthread_mutex_unlock (&(g_process_locale
.m_mutex
));
502 /**********************************************
503 osl_setProcessLocale().
504 *********************************************/
505 oslProcessError SAL_CALL
osl_setProcessLocale( rtl_Locale
* pLocale
)
507 oslProcessError result
= osl_Process_E_Unknown
;
509 OSL_PRECOND(pLocale
, "osl_setProcessLocale(): Invalid parameter.");
511 pthread_mutex_lock(&(g_process_locale
.m_mutex
));
512 if (_imp_setProcessLocale (pLocale
) == 0)
514 g_process_locale
.m_pLocale
= pLocale
;
515 result
= osl_Process_E_None
;
517 pthread_mutex_unlock (&(g_process_locale
.m_mutex
));