XRootD
XrdOucProg Class Reference

#include <XrdOucProg.hh>

+ Collaboration diagram for XrdOucProg:

Public Member Functions

 XrdOucProg (XrdSysError *errobj=0, int efd=-1)
 
 ~XrdOucProg ()
 
int Feed (const char *data)
 
int Feed (const char *data, int dlen)
 
int Feed (const char *data[], const int dlen[])
 
XrdOucStreamgetStream () const
 
bool isLocal ()
 
int Run (char *outBuff, int outBsz, const char *arg1=0, const char *arg2=0, const char *arg3=0, const char *arg4=0) const
 
int Run (const char *arg1=0, const char *arg2=0, const char *arg3=0, const char *arg4=0) const
 
int Run (const char *argV[], int argC, const char *envV[]=0) const
 
int Run (XrdOucStream *Sp, const char *arg1=0, const char *arg2=0, const char *arg3=0, const char *arg4=0) const
 
int Run (XrdOucStream *Sp, const char *argV[], int argc=0, const char *envV[]=0) const
 
int RunDone (XrdOucStream &cmd) const
 
int Setup (const char *prog, XrdSysError *errP=0, int(*Proc)(XrdOucStream *, char **, int)=0)
 
int Start (void)
 

Detailed Description

Definition at line 37 of file XrdOucProg.hh.

Constructor & Destructor Documentation

◆ XrdOucProg()

XrdOucProg::XrdOucProg ( XrdSysError errobj = 0,
int  efd = -1 
)
inline

Definition at line 45 of file XrdOucProg.hh.

46  : eDest(errobj), myStream(0), myProc(0), ArgBuff(0),
47  Arg(&ArgBuff), numArgs(0), theEFD(efd) {}

◆ ~XrdOucProg()

XrdOucProg::~XrdOucProg ( )

Definition at line 53 of file XrdOucProg.cc.

54 {
55  Reset();
56  if (myStream) delete myStream;
57 }

Member Function Documentation

◆ Feed() [1/3]

int XrdOucProg::Feed ( const char *  data)
inline

Definition at line 63 of file XrdOucProg.hh.

63 {return Feed(data, (int)strlen(data));}
int Feed(const char *data[], const int dlen[])
Definition: XrdOucProg.cc:63

References Feed().

Referenced by Feed().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Feed() [2/3]

int XrdOucProg::Feed ( const char *  data,
int  dlen 
)
inline

Definition at line 57 of file XrdOucProg.hh.

58  {const char *myData[2] = {data, 0};
59  const int myDlen[2] = {dlen, 0};
60  return Feed(myData, myDlen);
61  }

References Feed().

+ Here is the call graph for this function:

◆ Feed() [3/3]

int XrdOucProg::Feed ( const char *  data[],
const int  dlen[] 
)

Definition at line 63 of file XrdOucProg.cc.

64 {
65  static XrdSysMutex feedMutex;
66  XrdSysMutexHelper feedHelper;
67  int rc;
68 
69 // Make sure we have a stream
70 //
71  if (!myStream) return EPIPE;
72  feedHelper.Lock(&feedMutex);
73 
74 // Check if this command is still running
75 //
76  if (!myStream->isAlive() && !Restart())
77  {if (eDest) eDest->Emsg("Prog" "Unable to restart", Arg[0]);
78  return EPIPE;
79  }
80 
81 // Send the line to the program
82 //
83  if (!myStream->Put((const char **)data, (const int *)dlen)) return 0;
84  if (eDest)
85  eDest->Emsg("Prog", myStream->LastError(), "feed", Arg[0]);
86  if ((rc = Restart()))
87  {if (eDest) eDest->Emsg("Prog", rc, "restart", Arg[0]);
88  return EPIPE;
89  }
90  if (!myStream->Put((const char **)data, (const int *)dlen)) return 0;
91  if (eDest)
92  eDest->Emsg("Prog", myStream->LastError(), "refeed", Arg[0]);
93  return EPIPE;
94 }
int Put(const char *data, const int dlen)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
void Lock(XrdSysMutex *Mutex)

References XrdSysError::Emsg(), XrdOucStream::isAlive(), XrdOucStream::LastError(), XrdSysMutexHelper::Lock(), and XrdOucStream::Put().

Referenced by Feed(), XrdBwmLogger::sendEvents(), XrdOfsEvs::sendEvents(), and XrdOssSys::Stage_QT().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getStream()

XrdOucStream* XrdOucProg::getStream ( ) const
inline

Definition at line 68 of file XrdOucProg.hh.

68 {return myStream;}

Referenced by XrdFrmPurge::Init().

+ Here is the caller graph for this function:

◆ isLocal()

bool XrdOucProg::isLocal ( )
inline

Definition at line 72 of file XrdOucProg.hh.

72 {return myProc != 0;}

◆ Run() [1/5]

int XrdOucProg::Run ( char *  outBuff,
int  outBsz,
const char *  arg1 = 0,
const char *  arg2 = 0,
const char *  arg3 = 0,
const char *  arg4 = 0 
) const

Definition at line 216 of file XrdOucProg.cc.

219 {
220  XrdOucStream cmd;
221  char *lp, *tp;
222  int n, rc;
223 
224 // Execute the command
225 //
226  runWithVec(&cmd, rc);
227  if (rc) return rc;
228 
229 // Drain the first line to the output buffer
230 //
231  if (outBuff && outBsz > 0)
232  {if ((lp = cmd.GetLine()))
233  {while (*lp && *lp == ' ') lp++;
234  if ((n = strlen(lp)))
235  {tp = lp+n-1;
236  while(*tp-- == ' ') n--;
237  if (n >= outBsz) n = outBsz-1;
238  strncpy(outBuff, lp, n); outBuff += n;
239  }
240  }
241  *outBuff = 0;
242  }
243 
244 // Drain remaining output
245 //
246  while((lp = cmd.GetLine())) {}
247 
248 // All done
249 //
250  return RunDone(cmd);
251 }
#define runWithVec(strmP, theRC)
Definition: XrdOucProg.cc:100
int RunDone(XrdOucStream &cmd) const
Definition: XrdOucProg.cc:257
char * GetLine()

References XrdOucStream::GetLine(), RunDone(), and runWithVec.

+ Here is the call graph for this function:

◆ Run() [2/5]

int XrdOucProg::Run ( const char *  arg1 = 0,
const char *  arg2 = 0,
const char *  arg3 = 0,
const char *  arg4 = 0 
) const

Definition at line 192 of file XrdOucProg.cc.

194 {
195  XrdOucStream cmd;
196  char *lp;
197  int rc;
198 
199 // Execute the command
200 //
201  runWithVec(&cmd, rc);
202  if (rc) return rc;
203 
204 // Drain all output
205 //
206  while((lp = cmd.GetLine()))
207  if (eDest && *lp) eDest->Emsg("Run", lp);
208 
209 // All done
210 //
211  return RunDone(cmd);
212 }

References XrdSysError::Emsg(), XrdOucStream::GetLine(), RunDone(), and runWithVec.

+ Here is the call graph for this function:

◆ Run() [3/5]

int XrdOucProg::Run ( const char *  argV[],
int  argC,
const char *  envV[] = 0 
) const

Definition at line 156 of file XrdOucProg.cc.

157 {
158  XrdOucStream cmd;
159  char *lp;
160  int rc;
161 
162 // Execute the command
163 //
164  rc = Run(&cmd, argV, argC, envV);
165  if (rc) return rc;
166 
167 // Drain all output
168 //
169  while((lp = cmd.GetLine()))
170  if (eDest && *lp) eDest->Emsg("Run", lp);
171 
172 // All done
173 //
174  return RunDone(cmd);
175 }
int Run(XrdOucStream *Sp, const char *argV[], int argc=0, const char *envV[]=0) const
Definition: XrdOucProg.cc:108

References XrdSysError::Emsg(), XrdOucStream::GetLine(), Run(), and RunDone().

+ Here is the call graph for this function:

◆ Run() [4/5]

int XrdOucProg::Run ( XrdOucStream Sp,
const char *  arg1 = 0,
const char *  arg2 = 0,
const char *  arg3 = 0,
const char *  arg4 = 0 
) const

Definition at line 179 of file XrdOucProg.cc.

181 {
182  int rc;
183 
184 // Execute the command
185 //
186  runWithVec(Sp, rc);
187  return rc;
188 }

References runWithVec.

◆ Run() [5/5]

int XrdOucProg::Run ( XrdOucStream Sp,
const char *  argV[],
int  argc = 0,
const char *  envV[] = 0 
) const

Definition at line 108 of file XrdOucProg.cc.

110 {
111  char **myArgs;
112  int rc, totArgs = numArgs + argC;
113 
114 // If we have no program, return an error
115 //
116  if (!ArgBuff)
117  {if (eDest) eDest->Emsg("Run", "No program specified");
118  return -ENOEXEC;
119  }
120 
121 // Copy arguments to stack storage (we could avoid this but not with the stack).
122 //
123  myArgs = (char**)alloca(sizeof(char *) * (totArgs + 1));
124  if (numArgs) memcpy(myArgs, Arg, sizeof(char*)*numArgs);
125  if (argC) memcpy(&myArgs[numArgs], argV, sizeof(char*)*argC);
126  myArgs[totArgs] = 0;
127 
128 // If this is a local process then just execute it inline on this thread
129 //
130  if (myProc) return (*myProc)(Sp, myArgs, totArgs);
131 
132 // Execute the command, possibly setting an environment.
133 //
134  if (envV)
135  {XrdOucEnv progEnv, *oldEnv = Sp->SetEnv(&progEnv);
136  progEnv.PutPtr("XrdEnvars**", (void *)envV);
137  rc = Sp->Exec(myArgs, 1, theEFD);
138  Sp->SetEnv(oldEnv);
139  } else rc = Sp->Exec(myArgs, 1, theEFD);
140 
141 // Diagnose any errors
142 //
143  if (rc)
144  {rc = Sp->LastError();
145  if (eDest) eDest->Emsg("Run", rc, "execute", Arg[0]);
146  return -rc;
147  }
148 
149 // All done, caller will drain output
150 //
151  return 0;
152 }
void PutPtr(const char *varname, void *value)
Definition: XrdOucEnv.cc:316
int Exec(const char *, int inrd=0, int efd=0)
XrdOucEnv * SetEnv(XrdOucEnv *newEnv)

References XrdSysError::Emsg(), XrdOucStream::Exec(), XrdOucStream::LastError(), XrdOucEnv::PutPtr(), and XrdOucStream::SetEnv().

Referenced by XrdXrootdJob2Do::DoIt(), XrdOssSys::GetFile(), XrdOssSys::MSS_Xeq(), Run(), XrdOfsPrepGPIReal::PrepGRun::Run(), Start(), and XrdOfsTPCProg::Xeq().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RunDone()

int XrdOucProg::RunDone ( XrdOucStream cmd) const

Definition at line 257 of file XrdOucProg.cc.

258 {
259  int rc;
260 
261 // If this is an inline program then just return 0. There is no external process
262 // and the return code was returned at the time the inline process was run.
263 //
264  if (myProc) return 0;
265 
266 // Drain the command
267 //
268  rc = cmd.Drain();
269 
270 // Determine ending status
271 //
272  if (WIFSIGNALED(rc))
273  {if (eDest)
274  {char buff[16];
275  sprintf(buff, "%d", WTERMSIG(rc));
276  eDest->Emsg("Run", Arg[0], "killed by signal", buff);
277  }
278  return -EPIPE;
279  }
280  if (WIFEXITED(rc))
281  {rc = WEXITSTATUS(rc);
282  if (rc && eDest)
283  {char buff[16];
284  sprintf(buff, "%d", rc);
285  eDest->Emsg("Run", Arg[0], "ended with status", buff);
286  }
287  return -rc;
288  }
289  return 0; // We'll assume all went well here
290 }

References XrdOucStream::Drain(), and XrdSysError::Emsg().

Referenced by XrdXrootdJob2Do::DoIt(), Run(), XrdOfsPrepGPIReal::PrepGRun::Run(), and XrdOfsTPCProg::Xeq().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Setup()

int XrdOucProg::Setup ( const char *  prog,
XrdSysError errP = 0,
int(*)(XrdOucStream *, char **, int)  Proc = 0 
)

Definition at line 296 of file XrdOucProg.cc.

298 {
299  static const int maxArgs = 65;
300  char *argV[maxArgs];
301  int rc;
302 
303 // Prepare to handle the program
304 //
305  Reset();
306  if (!errP) errP = eDest;
307  myProc = 0;
308  ArgBuff = strdup(prog);
309 
310 // Construct the argv array based on passed command line.
311 //
312  rc = XrdOucUtils::argList(ArgBuff, argV, maxArgs);
313  if (rc <= 0)
314  {if (errP)
315  {if (!rc || !argV[0])
316  {const char *pgm = (Proc ? "procedure" : "program");
317  errP->Emsg("Run", pgm, "name not specified.");
318  } else errP->Emsg("Run", rc, "set up", argV[0]);
319  }
320  return (rc ? rc : -EINVAL);
321  }
322 
323 // Record the arguments including the phamtom null pointer. We must have
324 // atleast one, the program or procedure name.
325 //
326  numArgs = rc;
327  Arg = new char*[rc+1];
328  memcpy(Arg, argV, sizeof(char *) * (rc+1));
329 
330 // If this is a local process then just record its address
331 //
332  if ((myProc = Proc)) return 0;
333 
334 // Make sure the program is really executable
335 //
336  if (access(Arg[0], X_OK))
337  {rc = errno;
338  if (errP) errP->Emsg("Run", rc, "set up", Arg[0]);
339  Reset();
340  return rc;
341  }
342  return 0;
343 }
int access(const char *path, int amode)
static int argList(char *args, char **argV, int argC)
Definition: XrdOucUtils.cc:124

References access(), XrdOucUtils::argList(), and XrdSysError::Emsg().

Referenced by XrdOssSys::ConfigStage(), XrdOssSys::ConfigStageC(), XrdOfsTPCProg::Init(), XrdFrmPurge::Init(), XrdBwmLogger::Start(), XrdOfsEvs::Start(), and XrdOfsgetPrepare().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Start()

int XrdOucProg::Start ( void  )

Definition at line 349 of file XrdOucProg.cc.

350 {
351 
352 // Create a stream for this command (it is an eror if we are already started)
353 //
354  if (myStream) return EBUSY;
355  if (!(myStream = new XrdOucStream(eDest))) return ENOMEM;
356 
357 // Execute the command and let it linger
358 //
359  theEFD = 0;
360  return Run(myStream);
361 }

References Run().

Referenced by XrdOssSys::ConfigStageC(), XrdFrmPurge::Init(), XrdBwmLogger::Start(), and XrdOfsEvs::Start().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

The documentation for this class was generated from the following files: