#include "shell.hpp" void shell::c_run2 (std::string args) { // sanity checks if ( args.empty() ) { carp ("format: run [args] ..."); return; } std::string command = args; bool bg = false; // check if we run in background if ( command.rfind ("&") + 1 == command.length () ) { bg = true; command.erase (command.length () - 2); } // create io streams for job io saga::job::ostream in; saga::job::istream out; saga::job::istream err; saga::job::job job; // run job // Use 'host_' as target host. // use 'js_' as saga::job_service try { saga::job::description jd; std::vector elems; std::string :: iterator begin = command.begin (); std::string :: iterator end = command.end (); std::string :: iterator iter; char last = '\0'; std::string elem = ""; for ( iter = begin; iter != end; iter++ ) { // if we found an unescaped space: store elem if ( *iter == ' ' && last != '\\' && elem != "" ) { elems.push_back (elem); elem = ""; } else { // append char to elem if its anything else, but skip escapes if ( *iter != '\\' && last != '\\' ) { elem += *iter; } } // save the character last = *iter; } // store last elem if ( elem != "" ) { elems.push_back (elem); } jd.set_attribute ("Executable", elems[0]); jd.set_attribute ("Interactive", "True"); if ( elems.size () > 1 ) { std::vector arguments; for ( unsigned int i = 1; i < elems.size (); i++ ) { arguments.push_back (elems[i]); } jd.set_vector_attribute (saga::job::attributes::description_arguments, arguments); } job = js_.create_job (jd); in = job.get_stdin (); out = job.get_stdout (); err = job.get_stderr (); job.run (); } catch (std::exception const & e) { std::cout << "run failed: " << e.what() << std::endl; return; } // get job state saga::job::state state = job.get_state (); // check if that worked if ( state != saga::job::Running && state != saga::job::Done ) { carp ("run failed: " + command); } if ( bg ) { // store background jobs in process table std::string jobid (job.get_job_id()); int pid = jobs_.add (jobid, command, job); // output std::cout << " [" << pid << "] " << command << std::endl; std::cout << " " << jobid << std::endl; } else { // a foreground job is pulled for its stdout while ( true ) { char buffer[255]; // get stdout out.read (buffer, sizeof (buffer)); if ( out.gcount () > 0 ) { std::cout << std::string (buffer, out.gcount ()); } // get stderr err.read (buffer, sizeof (buffer)); if ( err.gcount () > 0 ) { std::cout << std::string (buffer, err.gcount ()); } if ( out.fail () || err.fail () ) { break; } } std::cout << std::endl << std::flush; } return; }