namespace/* private */
{ /* Function object that compares two strings that are expectedtobeenvironmentvariablesintheform "name=value".Onlythe'name'partwillbecompared. Thecomparisonisinuppercaseandreturnstrue ifthefirstofbothstringsislessthanthe
second one. */ struct less_environment_variable
{ booloperator() (const OUString& lhs, const OUString& rhs) const
{
OSL_ENSURE((lhs.indexOf(L'=') > -1) &&
(rhs.indexOf(L'=') > -1), "Malformed environment variable");
// Windows compares environment variables uppercase // so we do it, too return (rtl_ustr_compare_WithLength(
lhs.toAsciiUpperCase().pData->buffer,
lhs.indexOf(L'='),
rhs.toAsciiUpperCase().pData->buffer,
rhs.indexOf(L'=')) < 0);
}
};
/* Function object used by for_each algorithm to calculatethesumofthelengthofallstrings
in a string container. */ class sum_of_string_lengths
{ public:
void read_environment(/*out*/ std::vector<OUString>* environment)
{ // GetEnvironmentStrings returns a sorted list, Windows // sorts environment variables upper case
LPWSTR env = GetEnvironmentStringsW();
LPWSTR p = env;
while (size_t l = wcslen(p))
{
environment->push_back(OUString(o3tl::toU(p)));
p += l + 1;
}
FreeEnvironmentStringsW(env);
// it is apparently possible that the environment is not completely // sorted; Cygwin may append entries, which breaks the equal_range
std::stable_sort(environment->begin(), environment->end(),
less_environment_variable());
}
/* the environment list must be sorted, new values shouldeitherreplaceexistingonesorshouldbe addedtothelist,environmentvariableswill
be handled case-insensitive */ bool create_merged_environment(
rtl_uString* env_vars[],
sal_uInt32 env_vars_count, /*in|out*/ std::vector<OUString>* merged_env)
{
assert(env_vars && env_vars_count > 0 && merged_env);
read_environment(merged_env);
for (sal_uInt32 i = 0; i < env_vars_count; i++)
{
OUString env_var(env_vars[i]);
if (env_var.getLength() == 0) returnfalse;
auto iter_pair = std::equal_range(
merged_env->begin(),
merged_env->end(),
env_var,
less_environment_variable());
if (env_var.indexOf(L'=') == -1)
{
merged_env->erase(iter_pair.first, iter_pair.second);
} else
{ if (iter_pair.first != iter_pair.second) // found
*iter_pair.first = env_var; else// not found
merged_env->insert(iter_pair.first, env_var);
}
} returntrue;
}
// allocate enough space for the '\0'-separated environment strings and // a final '\0'
environment.resize(calc_sum_of_string_lengths(merged_env) + 1);
sal_uInt32 n = envv.getLength() + 1; // copy the final '\0', too
memcpy(&environment[pos], envv.getStr(), n * sizeof(sal_Unicode));
pos += n;
}
environment[pos] = 0; // append a final '\0'
returntrue;
}
/* In contrast to the Win32 API function CreatePipe with thisfunctionthecallerisabletodetermineseparately
which handle of the pipe is inheritable. */ bool create_pipe(
PHANDLE p_read_pipe, bool b_read_pipe_inheritable,
PHANDLE p_write_pipe, bool b_write_pipe_inheritable,
LPVOID p_security_descriptor = nullptr,
DWORD pipe_size = 0)
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = p_security_descriptor;
sa.bInheritHandle = b_read_pipe_inheritable || b_write_pipe_inheritable;
// Add a quote sign to the start and the end of a string // if not already present
OUString quote_string(const OUString& string)
{
OUStringBuffer quoted; if (string.indexOf(L'"') != 0)
quoted.append('"');
quoted.append(string);
if (string.lastIndexOf(L'"') != (string.getLength() - 1))
quoted.append('"');
return quoted.makeStringAndClear();
}
// The parameter path must be a system path. If it is longer than 260 characters // then it is shortened using the GetShortPathName function. This function only // works if the path exists. Because "path" can be the path to an executable, it // may not have the file extension ".exe". However, if the file on disk has the // ".exe" extension, then the function will fail. In this case a second attempt // is started by adding the parameter "extension" to "path".
OUString getShortPath(OUString const & path, OUString const & extension)
{
OUString ret(path); if (path.getLength() > 260)
{
std::vector<sal_Unicode> vec(path.getLength() + 1); //GetShortPathNameW only works if the file can be found! const DWORD len = GetShortPathNameW(
o3tl::toW(path.getStr()), o3tl::toW(vec.data()), path.getLength() + 1);
// Returns the system path of the executable which can either // be provided via the strImageName parameter or as first // element of the strArguments list. // The returned path will be quoted if it contains spaces.
OUString get_executable_path(
rtl_uString* image_name,
rtl_uString* cmdline_args[],
sal_uInt32 n_cmdline_args, bool search_path)
{
OUString exe_name;
if (image_name)
exe_name = image_name; elseif (n_cmdline_args)
exe_name = OUString(cmdline_args[0]);
OUString exe_url = exe_name; if (search_path)
osl_searchFileURL(exe_name.pData, nullptr, &exe_url.pData);
OUString exe_path; if (osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(exe_url, exe_path)) return OUString();
exe_path = getShortPath(exe_path, ".exe");
if (exe_path.indexOf(' ') != -1)
exe_path = quote_string(exe_path);
if (is_batch_file(exe_path))
{
OUString batch_processor = get_batch_processor();
if (batch_processor.getLength())
{ /* cmd.exe does not work without a console window */ if (!(Options & osl_Process_WAIT) || (Options & osl_Process_DETACHED))
flags |= CREATE_NEW_CONSOLE;
command_line.append(batch_processor + " /c ");
} else // should we return here in case of error? return osl_Process_E_Unknown;
}
command_line.append(exe_path);
/* Add remaining arguments to command line. If ustrImageName is nullptr thefirstparameteristhenameoftheexecutablesowehaveto
start at 1 instead of 0 */ for (sal_uInt32 n = (nullptr != ustrImageName) ? 0 : 1; n < nArguments; n++)
{
command_line.append(" ");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.