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 int main(int argc, char** argv)
00112 {
00113 ros::init(argc, argv, "screenrun");
00114
00115 if(argc > 1) {
00116 if(strcmp(argv[1], "b") == 0) {
00117 ROS_INFO("Using byobu for screen.");
00118 g_screen_cmd = "byobu";
00119 }
00120 }
00121
00122 ros::NodeHandle nh;
00123
00124 if(!load())
00125 return 1;
00126
00127 if(screenRunning()) {
00128 ROS_WARN("Screen \"ros\" already running, reusing this session");
00129 } else {
00130 ROS_INFO("Creating screen \"ros\"");
00131 if(!executeCmd(g_screen_cmd + " -S ros -d -m")) {
00132 ROS_FATAL("failed");
00133 return 1;
00134 }
00135 }
00136
00137 for(vector<ProgramEntry>::iterator it = programs.begin(); it != programs.end(); it++) {
00138 it->pushToScreen();
00139 }
00140
00141 return 0;
00142 }