Back to index

nordugrid-arc-nox  1.1.0~rc6
run_plugin.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #ifndef WIN32
00006 #include <dlfcn.h>
00007 #endif
00008 
00009 #include <arc/Run.h>
00010 
00011 #include "../conf/environment.h"
00012 #include "../conf/conf.h"
00013 #include "run_plugin.h"
00014 
00015 void free_args(char** args) {
00016   if(args == NULL) return;
00017   for(int i=0;args[i];i++) free(args[i]);
00018   free(args);
00019 }
00020 
00021 char** string_to_args(const std::string& command) {
00022   if(command.length() == 0) return NULL;
00023   int n = 100;
00024   char** args = (char**)malloc(n*sizeof(char**));
00025   int i;
00026   for(i=0;i<n;i++) args[i]=NULL;
00027   if(args == NULL) return NULL;
00028   std::string args_s = command;
00029   std::string arg_s;
00030   for(i=0;;i++) {
00031     if(i==(n-1)) {
00032       n+=10;
00033       char** args_ = (char**)realloc(args,n*sizeof(char**));
00034       if(args_ == NULL) {
00035         free_args(args);
00036         return NULL;
00037       };
00038       args=args_; for(int i_ = i;i_<n;i_++) args_[i_]=NULL;
00039     };
00040     arg_s=config_next_arg(args_s);
00041     if(arg_s.length() == 0) break;
00042     args[i]=strdup(arg_s.c_str());
00043     if(args[i] == NULL) {
00044       free_args(args);
00045       return NULL;
00046     };
00047   };
00048   return args;
00049 }
00050 
00051 
00052 void RunPlugin::set(const std::string& cmd) {
00053   args_.resize(0); lib="";
00054   char** args = string_to_args(cmd);
00055   if(args == NULL) return;
00056   for(char** arg = args;*arg;arg++) {
00057     args_.push_back(std::string(*arg));
00058   };
00059   free_args(args);
00060   if(args_.size() == 0) return;
00061   std::string& exc = *(args_.begin());
00062   if(exc[0] == '/') return;
00063   std::string::size_type n = exc.find('@');
00064   if(n == std::string::npos) return;
00065   std::string::size_type p = exc.find('/');
00066   if((p != std::string::npos) && (p < n)) return;
00067   lib=exc.substr(n+1); exc.resize(n);
00068   if(lib[0] != '/') lib="./"+lib;
00069 }
00070 
00071 void RunPlugin::set(char const * const * args) {
00072   args_.resize(0); lib="";
00073   if(args == NULL) return;
00074   for(char const * const * arg = args;*arg;arg++) {
00075     args_.push_back(std::string(*arg));
00076   };
00077   if(args_.size() == 0) return;
00078   std::string& exc = *(args_.begin());
00079   if(exc[0] == '/') return;
00080   std::string::size_type n = exc.find('@');
00081   if(n == std::string::npos) return;
00082   std::string::size_type p = exc.find('/');
00083   if((p != std::string::npos) && (p < n)) return;
00084   lib=exc.substr(n+1); exc.resize(n);
00085   if(lib[0] != '/') lib="./"+lib;
00086 }
00087 
00088 bool RunPlugin::run(void) {
00089   if(args_.size() == 0) return true;
00090   char** args = (char**)malloc(sizeof(char*)*(args_.size()+1));
00091   if(args == NULL) return false;
00092   int n = 0;
00093   for(std::list<std::string>::iterator i = args_.begin();
00094               i!=args_.end();++i,++n) args[n]=(char*)(i->c_str());
00095   args[n]=NULL;
00096   if(lib.length() == 0) {
00097     bool r = false;
00098     Arc::Run re(args_);
00099     re.AssignStdin(stdin_);
00100     re.AssignStdout(stdout_);
00101     re.AssignStderr(stderr_);
00102     if(re.Start()) {
00103       if(re.Wait(timeout_)) {
00104         result_=re.Result();
00105         r=true;
00106       } else {
00107         re.Kill(0);
00108       };
00109     };
00110     if(!r) {
00111       free(args);
00112       return false;
00113     };
00114   } else {
00115 #ifndef WIN32
00116     void* lib_h = dlopen(lib.c_str(),RTLD_NOW);
00117     if(lib_h == NULL) { free(args); return false; };
00118     lib_plugin_t f;
00119     f.v = dlsym(lib_h,args[0]);
00120     if(f.v == NULL) { dlclose(lib_h); free(args); return false; };
00121     result_ = (*f.f)(args[1],args[2],args[3],args[4],args[5],
00122                    args[6],args[7],args[8],args[9],args[10],
00123                    args[11],args[12],args[13],args[14],args[15],
00124                    args[16],args[17],args[18],args[19],args[20],
00125                    args[21],args[22],args[23],args[24],args[25],
00126                    args[26],args[27],args[28],args[29],args[30],
00127                    args[31],args[32],args[33],args[34],args[35],
00128                    args[36],args[37],args[38],args[39],args[40],
00129                    args[41],args[42],args[43],args[44],args[45],
00130                    args[56],args[57],args[58],args[59],args[60],
00131                    args[61],args[62],args[63],args[64],args[65],
00132                    args[66],args[67],args[68],args[69],args[70],
00133                    args[71],args[72],args[73],args[74],args[75],
00134                    args[76],args[77],args[78],args[79],args[80],
00135                    args[81],args[82],args[83],args[84],args[85],
00136                    args[86],args[87],args[88],args[89],args[90],
00137                    args[91],args[92],args[93],args[94],args[95],
00138                    args[96],args[97],args[98],args[99],args[100]);
00139     dlclose(lib_h);
00140 #else
00141 #warning Implement calling function from library for Windows
00142     result=-1;
00143 #endif
00144   };
00145   free(args);
00146   return true;
00147 }
00148 
00149 bool RunPlugin::run(substitute_t subst,void* arg) {
00150   result_=0; stdout_=""; stderr_="";
00151   if(subst == NULL) return run();
00152   if(args_.size() == 0) return true;
00153   char** args = (char**)malloc(sizeof(char*)*(args_.size()+1));
00154   if(args == NULL) return false;
00155   std::list<std::string> args__;
00156   for(std::list<std::string>::iterator i = args_.begin();i!=args_.end();++i) {
00157     args__.push_back(*i);
00158   };
00159   for(std::list<std::string>::iterator i = args__.begin();i!=args__.end();++i) {
00160     (*subst)(*i,arg);
00161   };
00162   int n = 0;
00163   for(std::list<std::string>::iterator i = args__.begin();
00164               i!=args__.end();++i,++n) args[n]=(char*)(i->c_str());
00165   args[n]=NULL;
00166   if(lib.length() == 0) {
00167     bool r = false;
00168     Arc::Run re(args_);
00169     re.AssignStdin(stdin_);
00170     re.AssignStdout(stdout_);
00171     re.AssignStderr(stderr_);
00172     if(re.Start()) {
00173       if(re.Wait(timeout_)) {
00174         result_=re.Result();
00175         r=true;
00176       } else {
00177         re.Kill(0);
00178       };
00179     };
00180     if(!r) {
00181       free(args);
00182       return false;
00183     };
00184   } else {
00185 #ifndef WIN32
00186     void* lib_h = dlopen(lib.c_str(),RTLD_NOW);
00187     if(lib_h == NULL) { 
00188       free(args); return false;
00189     };
00190     lib_plugin_t f;
00191     f.v = dlsym(lib_h,args[0]);
00192     if(f.v == NULL) { 
00193       dlclose(lib_h); free(args); return false;
00194     };
00195     result_ = (*f.f)(args[1],args[2],args[3],args[4],args[5],
00196                    args[6],args[7],args[8],args[9],args[10],
00197                    args[11],args[12],args[13],args[14],args[15],
00198                    args[16],args[17],args[18],args[19],args[20],
00199                    args[21],args[22],args[23],args[24],args[25],
00200                    args[26],args[27],args[28],args[29],args[30],
00201                    args[31],args[32],args[33],args[34],args[35],
00202                    args[36],args[37],args[38],args[39],args[40],
00203                    args[41],args[42],args[43],args[44],args[45],
00204                    args[56],args[57],args[58],args[59],args[60],
00205                    args[61],args[62],args[63],args[64],args[65],
00206                    args[66],args[67],args[68],args[69],args[70],
00207                    args[71],args[72],args[73],args[74],args[75],
00208                    args[76],args[77],args[78],args[79],args[80],
00209                    args[81],args[82],args[83],args[84],args[85],
00210                    args[86],args[87],args[88],args[89],args[90],
00211                    args[91],args[92],args[93],args[94],args[95],
00212                    args[96],args[97],args[98],args[99],args[100]);
00213     dlclose(lib_h);
00214 #else
00215 #warning Implement calling function from library for Windows
00216     result=-1;
00217 #endif
00218   };
00219   free(args);
00220   return true;
00221 }
00222 
00223 void RunPlugins::add(const std::string& cmd) {
00224   RunPlugin* r = new RunPlugin(cmd);
00225   if(!r) return;
00226   if(!(*r)) return;
00227   plugins_.push_back(r);
00228 }
00229 
00230 bool RunPlugins::run(void) {
00231   for(std::list<RunPlugin*>::iterator r = plugins_.begin();
00232                                   r != plugins_.end();++r) {
00233     if(!(*r)->run()) return false;
00234     if((*r)->result() != 0) {
00235       result_=result(); return true;
00236     };
00237   };
00238   result_=0;
00239   return true;
00240 }
00241 
00242 bool RunPlugins::run(RunPlugin::substitute_t subst,void* arg) {
00243   for(std::list<RunPlugin*>::iterator r = plugins_.begin();
00244                                   r != plugins_.end();++r) {
00245     if(!(*r)->run(subst,arg)) return false;
00246     if((*r)->result() != 0) {
00247       result_=result(); return true;
00248     };
00249   };
00250   result_=0;
00251   return true;
00252 }
00253