コード例 #1
0
/**
 * Converts an environment to a char** table as used by execve().
 *
 * Converts the environment's contents to the format used by the
 * execve() system call. The returned char** array is allocated
 * in dynamic memory; the caller must free it when not used any
 * more. Each entry is also allocated in dynamic memory and is a
 * NULL-terminated string of the form var=value; these must also be
 * released by the caller.
 *
 * This operation is only available on POSIX systems.
 *
 * \return The first argument of the pair is an integer that indicates
 *         how many strings are stored in the second argument. The
 *         second argument is a NULL-terminated, dynamically allocated
 *         array of dynamically allocated strings representing the
 *         enviroment's content. Each array entry is a NULL-terminated
 *         string of the form var=value. The caller is responsible for
 *         freeing them.
 */
inline std::pair<std::size_t, char **>
environment_to_envp(const environment
                    &env) {
  std::size_t nargs = env.size();
  char **envp = new char *[nargs + 1];
  environment::size_type i = 0;
  for (environment::const_iterator it = env.begin(); it != env.end(); ++it) {
    std::string s = it->first + "=" + it->second;
    envp[i] = new char[s.size() + 1];
    std::strncpy(envp[i], s.c_str(), s.size() + 1);
    ++i;
  }
  envp[i] = 0;
  return std::pair<std::size_t, char **>(nargs, envp);
} // environment_to_envp
コード例 #2
0
ファイル: posix_ops.hpp プロジェクト: iamnilay3/openlierox
inline
pid_t
posix_start(const Executable& exe,
            const Arguments& args,
            const environment& env,
            info_map& infoin,
            info_map& infoout,
            const posix_setup& setup)
{
    pid_t pid = ::fork();
    if (pid == -1) {
        boost::throw_exception
            (system_error("boost::process::detail::posix_start",
                          "fork(2) failed", errno));
    } else if (pid == 0) {
#if defined(F_MAXFD)
        int maxdescs = std::max(::fcntl(0, F_MAXFD), 128); // XXX
#else
        int maxdescs = 128; // XXX
#endif
        try {
            boost::scoped_array< bool > closeflags(new bool[maxdescs]);
            for (int i = 0; i < maxdescs; i++)
                closeflags.get()[i] = true;

            setup_input(infoin, closeflags.get(), maxdescs);
            setup_output(infoout, closeflags.get(), maxdescs);

            for (int i = 0; i < maxdescs; i++)
                if (closeflags.get()[i])
                    ::close(i);

            setup();
        } catch (const system_error& e) {
            ::write(STDERR_FILENO, e.what(), std::strlen(e.what()));
            ::write(STDERR_FILENO, "\n", 1);
            ::exit(EXIT_FAILURE);
        }

        std::pair< std::size_t, char** > argcv =
            collection_to_posix_argv(args);
        char** envp = environment_to_envp(env);
        ::execve(exe.c_str(), argcv.second, envp);
        system_error e("boost::process::detail::posix_start",
                       "execve(2) failed", errno);

        for (std::size_t i = 0; i < argcv.first; i++)
            delete [] argcv.second[i];
        delete [] argcv.second;

        for (std::size_t i = 0; i < env.size(); i++)
            delete [] envp[i];
        delete [] envp;

        ::write(STDERR_FILENO, e.what(), std::strlen(e.what()));
        ::write(STDERR_FILENO, "\n", 1);
        ::exit(EXIT_FAILURE);
    }

    BOOST_ASSERT(pid > 0);

    for (info_map::iterator iter = infoin.begin();
         iter != infoin.end(); iter++) {
        stream_info& si = (*iter).second;

        if (si.m_type == stream_info::use_pipe)
            si.m_pipe->rend().close();
    }

    for (info_map::iterator iter = infoout.begin();
         iter != infoout.end(); iter++) {
        stream_info& si = (*iter).second;

        if (si.m_type == stream_info::use_pipe)
            si.m_pipe->wend().close();
    }

    return pid;
}