screenrun.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 #include <stdio.h>
00003 #include <dirent.h>
00004 #include <stdlib.h>
00005 #include <vector>
00006 #include <string>
00007 using namespace std;
00008 
00009 string g_screen_cmd = "screen";
00010 
00011 bool executeCmd(const string & cmd)
00012 {
00013     int ret = system(cmd.c_str());
00014     if(ret != 0) {
00015         perror("executeCmd");
00016         ROS_ERROR("Command \"%s\" returned %d", cmd.c_str(), ret);
00017         return false;
00018     }
00019     return true;
00020 }
00021 
00022 class ProgramEntry
00023 {
00024     public:
00025         string name;
00026         vector<string> commands;
00027 
00028         void pushToScreen() {
00029             ROS_INFO("Creating screen window for \"%s\"", name.c_str());
00030             if(!executeCmd(g_screen_cmd + " -S ros -X screen -t '" + name + "'"))
00031                 return;
00032             for(vector<string>::iterator it = commands.begin(); it != commands.end(); it++) {
00033                 ROS_INFO("Pushing command: \"%s\"", it->c_str());
00034                 if(!executeCmd(g_screen_cmd + " -p '" + name + "' -S ros -X eval 'stuff \"" + *it + "\"'"))
00035                     return;
00036             }
00037         }
00038 };
00039 
00040 vector<ProgramEntry> programs;
00041 
00042 bool load()
00043 {
00044     ros::NodeHandle nh("~");
00045 
00046     XmlRpc::XmlRpcValue xmlRpc;
00047     if(!nh.getParam("programs", xmlRpc)) {
00048         ROS_FATAL("No programs defined.");
00049         return false;
00050     } 
00051 
00052     if(xmlRpc.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00053         ROS_FATAL("programs param should be a list.");
00054         return false;
00055     }
00056     if(xmlRpc.size() == 0) {
00057         ROS_FATAL("programs list is empty.");
00058         return false;
00059     }
00060 
00061     for(int i = 0; i < xmlRpc.size(); i++) {
00062         ProgramEntry pe;
00063 
00064         if(xmlRpc[i].getType() != XmlRpc::XmlRpcValue::TypeStruct) {
00065             ROS_FATAL("programs entry %d is not of type string.", i);
00066             return false;
00067         }
00068         pe.name = (string)xmlRpc[i]["name"];
00069         XmlRpc::XmlRpcValue cmds = xmlRpc[i]["commands"];
00070         if(cmds.getType() != XmlRpc::XmlRpcValue::TypeArray) {
00071             ROS_FATAL("commands for %s is not a list", pe.name.c_str());
00072             return false;
00073         }
00074         for(int j = 0; j < cmds.size(); j++) {
00075             pe.commands.push_back((string)cmds[j]);
00076         }
00077 
00078         programs.push_back(pe);
00079     }
00080 
00081     return true;
00082 }
00083 
00084 string getScreenPath()
00085 {
00086     char* user = getenv("USER");
00087     if(!user)
00088         return "";
00089 
00090     return string("/var/run/screen/S-") + user;
00091 }
00092 
00093 bool screenRunning()
00094 {
00095     string sp = getScreenPath();
00096     if(sp.empty())
00097         return false;
00098 
00099     DIR* dir = opendir(sp.c_str());
00100     if(!dir)
00101         return false;
00102     struct dirent* entry;
00103     while( (entry = readdir(dir)) ) {
00104         string dname = entry->d_name;
00105         if(dname.find("ros") != string::npos)
00106             return true;
00107     }
00108     return false;
00109 }
00110 
00111 bool byobu_exists()
00112 {
00113     int ret = system("which byobu > /dev/null");
00114     return ret == 0;
00115 }
00116 
00117 int main(int argc, char** argv)
00118 {
00119     ros::init(argc, argv, "screenrun");
00120 
00121     if(argc > 1) {
00122         if(strcmp(argv[1], "b") == 0) {
00123             if(!byobu_exists()) {
00124                 ROS_ERROR("Requested byobu for screen, but cannot find byobu executable. Install byobu for this. Falling back to screen for now.");
00125             } else {
00126                 ROS_INFO("Using byobu for screen.");
00127                 g_screen_cmd = "byobu";
00128             }
00129         }
00130     }
00131 
00132     ros::NodeHandle nh;
00133 
00134     if(!load())
00135         return 1;
00136 
00137     if(screenRunning()) {
00138         ROS_WARN("Screen \"ros\" already running, reusing this session");
00139     } else {
00140         ROS_INFO("Creating screen \"ros\"");
00141         if(!executeCmd(g_screen_cmd + " -S ros -d -m")) {
00142             ROS_FATAL("failed");
00143             return 1;
00144         }
00145     }
00146 
00147     for(vector<ProgramEntry>::iterator it = programs.begin(); it != programs.end(); it++) {
00148         it->pushToScreen();
00149     }
00150 
00151     return 0;
00152 }


screenrun
Author(s): Christian Dornhege
autogenerated on Fri Aug 28 2015 13:00:39