// Copyright (c) 2005-2008 Andre Merzky // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include "saga-shell.hpp" #include int shell::c_run (std::vector & args, props & p) { // sanity checks if ( args.empty () ) { carp ("format: run [args] ...", p); return FAILURE; } bool bg = false; // check if we run in background if ( !args.empty() && args.back () == "&" ) { bg = true; args.erase ((++args.rbegin()).base()); // erase last element } std::string command; std::vector :: iterator begin = args.begin (); std::vector :: iterator end = args.end (); std::vector :: iterator iter; for ( iter = begin; iter != end; ++iter ) { command += *iter; command += " "; } // create io streams for job io saga::job::ostream in; saga::job::istream out; saga::job::istream err; saga::job::job job; try { job = js_.run_job (host_, command, in, out, err); } catch (std::exception const & e) { p.err += "run failed: "; p.err += e.what(); p.err += "\n"; return FAILURE; } catch (...) { std::cerr << "ARGHH... very bad." << std::endl; return FAILURE; } // get job state saga::job::state state = job.get_state (); // check if that worked if ( state != saga::job::Running && state != saga::job::Done ) { std::string exitcode; if (job.attribute_exists(saga::job::attributes::exitcode)) { exitcode = job.get_attribute(saga::job::attributes::exitcode); carp ("run failed: " + command + // ", state: " + saga::job::get_state_name(state) + ", exitcode: " + exitcode, p); } else { carp ("run failed: " + command ); // ", state: " + saga::job::get_state_name(state), p); } return FAILURE; } if ( bg ) { // store background jobs in process table std::string jobid (job.get_job_id()); int pid = jobs_.add (jobid, command, job); // output p.out += " ["; p.out += boost::lexical_cast(pid); p.out += "] "; p.out += command; p.out += "\n"; p.out += " "; p.out += jobid; p.out += "\n"; } else { while ( true ) { char buffer[255]; // get stdout out.read (buffer, sizeof (buffer)); err.read (buffer, sizeof (buffer)); if ( out.gcount () > 0 ) { p.out += std::string (buffer, out.gcount ()); } if ( err.gcount () > 0 ) { p.out += std::string (buffer, err.gcount ()); } if ( out.fail () && err.fail () ) { break; } } p.out += "\n"; } return SUCCESS; }