Back to index

nordugrid-arc-nox  1.1.0~rc6
run_redirected.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <unistd.h>
00006 #include <sys/types.h>
00007 #include <sys/stat.h>
00008 #include <fcntl.h>
00009 
00010 #include <arc/Logger.h>
00011 
00012 #include "../conf/environment.h"
00013 #include "run_redirected.h"
00014 
00015 static Arc::Logger& logger = Arc::Logger::getRootLogger();
00016 
00017 int RunRedirected::run(JobUser& user,const char* cmdname,int in,int out,int err,char *const args[],int timeout) {
00018   std::list<std::string> args_;
00019   for(int n = 0;args[n];++n) args_.push_back(std::string(args[n]));
00020   Arc::Run re(args_);
00021   if(!re) {
00022     logger.msg(Arc::ERROR,"%s: Failure creating slot for child process",cmdname?cmdname:"");
00023     return -1;
00024   };
00025   RunRedirected* rr = new RunRedirected(user,cmdname,in,out,err);
00026   if((!rr) || (!(*rr))) {
00027     if(rr) delete rr;
00028     logger.msg(Arc::ERROR,"%s: Failure creating data storage for child process",cmdname?cmdname:"");
00029     return -1;
00030   };
00031   re.AssignInitializer(&initializer,rr);
00032   re.KeepStdin(true);
00033   re.KeepStdout(true);
00034   re.KeepStderr(true);
00035   if(!re.Start()) {
00036     delete rr;
00037     logger.msg(Arc::ERROR,"%s: Failure starting child process",cmdname?cmdname:"");
00038     return -1;
00039   };
00040   delete rr;
00041   if(!re.Wait(timeout)) {
00042     logger.msg(Arc::ERROR,"%s: Failure waiting for child process to finish",cmdname?cmdname:"");
00043     return -1;
00044   };
00045   return re.Result();
00046 }
00047 
00048 int RunRedirected::run(JobUser& user,const char* cmdname,int in,int out,int err,const char* cmd,int timeout) {
00049   Arc::Run re(cmd);
00050   if(!re) {
00051     logger.msg(Arc::ERROR,"%s: Failure creating slot for child process",cmdname?cmdname:"");
00052     return -1;
00053   };
00054   RunRedirected* rr = new RunRedirected(user,cmdname,in,out,err);
00055   if((!rr) || (!(*rr))) {
00056     if(rr) delete rr;
00057     logger.msg(Arc::ERROR,"%s: Failure creating data storage for child process",cmdname?cmdname:"");
00058     return -1;
00059   };
00060   re.AssignInitializer(&initializer,rr);
00061   re.KeepStdin(true);
00062   re.KeepStdout(true);
00063   re.KeepStderr(true);
00064   if(!re.Start()) {
00065     delete rr;
00066     logger.msg(Arc::ERROR,"%s: Failure starting child process",cmdname?cmdname:"");
00067     return -1;
00068   };
00069   delete rr;
00070   if(!re.Wait(timeout)) {
00071     logger.msg(Arc::ERROR,"%s: Failure waiting for child process to finish",cmdname?cmdname:"");
00072     return -1;
00073   };
00074   return re.Result();
00075 }
00076 
00077 void RunRedirected::initializer(void* arg) {
00078 #ifdef WIN32
00079 #error This functionality is not available in Windows environement
00080 #else
00081   // child
00082   RunRedirected* it = (RunRedirected*)arg;
00083   struct rlimit lim;
00084   int max_files;
00085   if(getrlimit(RLIMIT_NOFILE,&lim) == 0) { max_files=lim.rlim_cur; }
00086   else { max_files=4096; };
00087   // change user
00088   if(!(it->user_.SwitchUser(true))) {
00089     logger.msg(Arc::ERROR,"%s: Failed switching user",it->cmdname_); sleep(10); exit(1);
00090   };
00091   // set up stdin,stdout and stderr
00092   if(it->stdin_ != -1)  dup2(it->stdin_,0);
00093   if(it->stdout_ != -1) dup2(it->stdout_,1);
00094   if(it->stderr_ != -1) dup2(it->stderr_,2);
00095   // close all handles inherited from parent
00096   if(max_files == RLIM_INFINITY) max_files=4096;
00097   for(int i=3;i<max_files;i++) { close(i); };
00098 #endif
00099 }
00100