XRootD
Loading...
Searching...
No Matches
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}
void Lock(XrdSysMutex *Mutex)

References XrdSysMutexHelper::Lock().

Referenced by Feed().

+ 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;}

◆ 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)
int RunDone(XrdOucStream &cmd) const
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 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

References 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:298
XrdOucEnv * SetEnv(XrdOucEnv *newEnv)
int Exec(const char *, int inrd=0, int efd=0)

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

Referenced by Run(), and Start().

+ 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().

Referenced by Run(), Run(), and Run().

+ 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(* Proc )(XrdOucStream *, char **, int) = 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}
#define access(a, b)
Definition XrdPosix.hh:39
static int argList(char *args, char **argV, int argC)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)

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

+ Here is the call 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().

+ Here is the call graph for this function:

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