/* A small C++ wrapper for the g_spawn_* functions from glib. It returns -1 on error, otherwise whatever the return value is. This shows how awful C code can get when written by someone too used to C++. Copyright (C) 2004 Walter Landry This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 dated June, 1991. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Spawn.hpp" #include #include #include #include #include "boost/filesystem/path.hpp" #include "boost/filesystem/fstream.hpp" #include "arx_error.hpp" /* Unix specific stuff here. */ #include using namespace std; bool Spawn::execute(int &return_exit_status, bool sync) const { /* Set up the arguments */ const int N=commands.size(); char *args[N+1]; int j=0; for(std::list::const_iterator i=commands.begin(); i!=commands.end(); ++i, ++j) { args[j]=new char[i->size()+1]; std::strcpy(args[j],i->c_str()); } args[j]=NULL; /* Set up the environment */ const int M=environment.size(); char *env[M+1]; j=0; for(std::list::const_iterator i=environment.begin(); i!=environment.end(); ++i, ++j) { env[j]=new char[i->size()+1]; std::strcpy(env[j],i->c_str()); } env[j]=NULL; char **temp_env; if(M==0) { temp_env=NULL; } else { temp_env=env; } gboolean result(FALSE); /* If running synchronously. */ if(sync) { gint exit_status; if(output.empty() && error.empty()) { result=g_spawn_sync(NULL,args,temp_env,flags,NULL,NULL, NULL,NULL,&exit_status,NULL); /* Unix specific stuff here to wait for the result and interpret the result. */ if(WIFEXITED(exit_status)) { return_exit_status=WEXITSTATUS(exit_status); } else { result=FALSE; } } else { /* Redirect stdout and stderr. */ gchar *output_string, *error_string; result=g_spawn_sync(NULL,args,temp_env,flags,NULL,NULL, &output_string,&error_string,&exit_status,NULL); /* Unix specific stuff here to wait for the result and interpret the result. */ if(WIFEXITED(exit_status)) { return_exit_status=WEXITSTATUS(exit_status); } else { result=FALSE; } /* Write the output and error files */ if(!output.empty()) { boost::filesystem::ofstream output_file(output); output_file << output_string; } g_free(output_string); if(!error.empty()) { boost::filesystem::ofstream error_file(error); error_file << error_string; } g_free(error_string); } } else { /* Async execution. Much simpler. */ result=g_spawn_async(NULL,args,temp_env,flags,NULL,NULL,NULL,NULL); } /* Free the arguments and environment */ for(j=0;j