ian@0: // ian@0: // Boost.Process ian@0: // ~~~~~~~~~~~~~ ian@0: // ian@0: // Copyright (c) 2006, 2007 Julio M. Merino Vidal ian@0: // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling ian@0: // Copyright (c) 2009 Boris Schaeling ian@0: // Copyright (c) 2010 Felipe Tanus, Boris Schaeling ian@0: // ian@0: // Distributed under the Boost Software License, Version 1.0. (See accompanying ian@0: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ian@0: // ian@0: ian@0: /** ian@0: * \file boost/process/detail/windows_helpers.hpp ian@0: * ian@0: * Includes the declaration of helper functions for Windows systems. ian@0: */ ian@0: ian@0: #ifndef BOOST_PROCESS_WINDOWS_HELPERS_HPP ian@0: #define BOOST_PROCESS_WINDOWS_HELPERS_HPP ian@0: ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: ian@0: namespace boost { ian@0: namespace process { ian@0: namespace detail { ian@0: ian@0: /** ian@0: * Converts an environment to a string used by CreateProcess(). ian@0: * ian@0: * Converts the environment's contents to the format used by the ian@0: * CreateProcess() system call. The returned char* string is ian@0: * allocated in dynamic memory; the caller must free it when not ian@0: * used any more. This is enforced by the use of a shared pointer. ian@0: * ian@0: * This operation is only available on Windows systems. ian@0: * ian@0: * \return A dynamically allocated char* string that represents ian@0: * the environment's content. This string is of the form ian@0: * var1=value1\\0var2=value2\\0\\0. ian@0: */ ian@0: inline boost::shared_array environment_to_windows_strings(environment ian@0: &env) ian@0: { ian@0: boost::shared_array envp; ian@0: ian@0: if (env.empty()) ian@0: { ian@0: envp.reset(new char[2]); ian@0: ZeroMemory(envp.get(), 2); ian@0: } ian@0: else ian@0: { ian@0: std::string s; ian@0: for (environment::const_iterator it = env.begin(); it != env.end(); ian@0: ++it) ian@0: { ian@0: s += it->first + "=" + it->second; ian@0: s.push_back(0); ian@0: } ian@0: envp.reset(new char[s.size() + 1]); ian@0: #if (BOOST_MSVC >= 1400) ian@0: memcpy_s(envp.get(), s.size() + 1, s.c_str(), s.size() + 1); ian@0: #else ian@0: memcpy(envp.get(), s.c_str(), s.size() + 1); ian@0: #endif ian@0: } ian@0: ian@0: return envp; ian@0: } ian@0: ian@0: /** ian@0: * Converts the command line to a plain string. ian@0: * ian@0: * Converts the command line's list of arguments to the format expected by the ian@0: * \a lpCommandLine parameter in the CreateProcess() system call. ian@0: * ian@0: * This operation is only available on Windows systems. ian@0: * ian@0: * \return A dynamically allocated string holding the command line ian@0: * to be passed to the executable. It is returned in a ian@0: * shared_array object to ensure its release at some point. ian@0: */ ian@0: template ian@0: inline boost::shared_array collection_to_windows_cmdline(const Arguments ian@0: &args) ian@0: { ian@0: typedef std::vector arguments_t; ian@0: arguments_t args2; ian@0: typename Arguments::size_type i = 0; ian@0: std::size_t size = 0; ian@0: for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ian@0: ++it) ian@0: { ian@0: std::string arg = *it; ian@0: ian@0: std::string::size_type pos = 0; ian@0: while ( (pos = arg.find('"', pos)) != std::string::npos) ian@0: { ian@0: arg.replace(pos, 1, "\\\""); ian@0: pos += 2; ian@0: } ian@0: ian@0: if (arg.find(' ') != std::string::npos) ian@0: arg = '\"' + arg + '\"'; ian@0: ian@0: if (i++ != args.size() - 1) ian@0: arg += ' '; ian@0: ian@0: args2.push_back(arg); ian@0: size += arg.size() + 1; ian@0: } ian@0: ian@0: boost::shared_array cmdline(new char[size]); ian@0: cmdline.get()[0] = '\0'; ian@0: for (arguments_t::size_type i = 0; i < args.size(); ++i) ian@0: #if (BOOST_MSVC >= 1400) ian@0: strcat_s(cmdline.get(), size, args2[i].c_str()); ian@0: #else ian@0: strncat(cmdline.get(), args2[i].c_str(), args2[i].size()); ian@0: #endif ian@0: ian@0: return cmdline; ian@0: } ian@0: ian@0: } ian@0: } ian@0: } ian@0: ian@0: #endif