// -*- c++ -*- /* $Id: spawn.ccg,v 1.3 2002/10/23 01:48:03 daniel Exp $ */ /* Copyright (C) 2002 The gtkmm Development Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include namespace { /* Helper callback to invoke the actual sigc++ slot. * We don't need to worry about (un)referencing, since the * child process gets its own copy of the parent's memory anyway. */ void child_setup_callback(void* user_data) { try { SigC::Slot0 slot (static_cast(user_data)); slot(); } catch(...) { Glib::exception_handlers_invoke(); } } void copy_output_buf(std::string* dest, const char* buf) { if(dest) { if(buf) *dest = buf; else dest->erase(); } } } namespace Glib { /**** process spawning functions *******************************************/ void spawn_async_with_pipes(const std::string& working_directory, const Glib::ArrayHandle& argv, const Glib::ArrayHandle& envp, SpawnFlags flags, const SigC::Slot0& child_setup, int* child_pid, int* standard_input, int* standard_output, int* standard_error) { const bool setup_slot = !child_setup.empty(); GError* error = 0; g_spawn_async_with_pipes( working_directory.c_str(), const_cast(argv.data()), const_cast(envp.data()), static_cast(unsigned(flags)), (setup_slot) ? &child_setup_callback : 0, (setup_slot) ? child_setup.impl() : 0, child_pid, standard_input, standard_output, standard_error, &error); if(error) Glib::Error::throw_exception(error); } void spawn_async_with_pipes(const std::string& working_directory, const Glib::ArrayHandle& argv, SpawnFlags flags, const SigC::Slot0& child_setup, int* child_pid, int* standard_input, int* standard_output, int* standard_error) { const bool setup_slot = !child_setup.empty(); GError* error = 0; g_spawn_async_with_pipes( working_directory.c_str(), const_cast(argv.data()), 0, static_cast(unsigned(flags)), (setup_slot) ? &child_setup_callback : 0, (setup_slot) ? child_setup.impl() : 0, child_pid, standard_input, standard_output, standard_error, &error); if(error) Glib::Error::throw_exception(error); } void spawn_async(const std::string& working_directory, const Glib::ArrayHandle& argv, const Glib::ArrayHandle& envp, SpawnFlags flags, const SigC::Slot0& child_setup, int* child_pid) { const bool setup_slot = !child_setup.empty(); GError* error = 0; g_spawn_async( working_directory.c_str(), const_cast(argv.data()), const_cast(envp.data()), static_cast(unsigned(flags)), (setup_slot) ? &child_setup_callback : 0, (setup_slot) ? child_setup.impl() : 0, child_pid, &error); if(error) Glib::Error::throw_exception(error); } void spawn_async(const std::string& working_directory, const Glib::ArrayHandle& argv, SpawnFlags flags, const SigC::Slot0& child_setup, int* child_pid) { const bool setup_slot = !child_setup.empty(); GError* error = 0; g_spawn_async( working_directory.c_str(), const_cast(argv.data()), 0, static_cast(unsigned(flags)), (setup_slot) ? &child_setup_callback : 0, (setup_slot) ? child_setup.impl() : 0, child_pid, &error); if(error) Glib::Error::throw_exception(error); } void spawn_sync(const std::string& working_directory, const Glib::ArrayHandle& argv, const Glib::ArrayHandle& envp, SpawnFlags flags, const SigC::Slot0& child_setup, std::string* standard_output, std::string* standard_error, int* exit_status) { const bool setup_slot = !child_setup.empty(); Glib::ScopedPtr buf_standard_output; Glib::ScopedPtr buf_standard_error; GError* error = 0; g_spawn_sync( working_directory.c_str(), const_cast(argv.data()), const_cast(envp.data()), static_cast(unsigned(flags)), (setup_slot) ? &child_setup_callback : 0, (setup_slot) ? child_setup.impl() : 0, (standard_output) ? buf_standard_output.addr() : 0, (standard_error) ? buf_standard_error.addr() : 0, exit_status, &error); if(error) Glib::Error::throw_exception(error); copy_output_buf(standard_output, buf_standard_output.get()); copy_output_buf(standard_error, buf_standard_error.get()); } void spawn_sync(const std::string& working_directory, const Glib::ArrayHandle& argv, SpawnFlags flags, const SigC::Slot0& child_setup, std::string* standard_output, std::string* standard_error, int* exit_status) { const bool setup_slot = !child_setup.empty(); Glib::ScopedPtr buf_standard_output; Glib::ScopedPtr buf_standard_error; GError* error = 0; g_spawn_sync( working_directory.c_str(), const_cast(argv.data()), 0, static_cast(unsigned(flags)), (setup_slot) ? &child_setup_callback : 0, (setup_slot) ? child_setup.impl() : 0, (standard_output) ? buf_standard_output.addr() : 0, (standard_error) ? buf_standard_error.addr() : 0, exit_status, &error); if(error) Glib::Error::throw_exception(error); copy_output_buf(standard_output, buf_standard_output.get()); copy_output_buf(standard_error, buf_standard_error.get()); } void spawn_command_line_async(const std::string& command_line) { GError* error = 0; g_spawn_command_line_async(command_line.c_str(), &error); if(error) Glib::Error::throw_exception(error); } void spawn_command_line_sync(const std::string& command_line, std::string* standard_output, std::string* standard_error, int* exit_status) { Glib::ScopedPtr buf_standard_output; Glib::ScopedPtr buf_standard_error; GError* error = 0; g_spawn_command_line_sync( command_line.c_str(), (standard_output) ? buf_standard_output.addr() : 0, (standard_error) ? buf_standard_error.addr() : 0, exit_status, &error); if(error) Glib::Error::throw_exception(error); copy_output_buf(standard_output, buf_standard_output.get()); copy_output_buf(standard_error, buf_standard_error.get()); } } // namespace Glib