XRootD
XrdOucStream.hh
Go to the documentation of this file.
1 #ifndef __OOUC_STREAM__
2 #define __OOUC_STREAM__
3 /******************************************************************************/
4 /* */
5 /* X r d O u c S t r e a m . h h */
6 /* */
7 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
8 /* Produced by Andrew Hanushevsky for Stanford University under contract */
9 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
10 /* */
11 /* This file is part of the XRootD software suite. */
12 /* */
13 /* XRootD is free software: you can redistribute it and/or modify it under */
14 /* the terms of the GNU Lesser General Public License as published by the */
15 /* Free Software Foundation, either version 3 of the License, or (at your */
16 /* option) any later version. */
17 /* */
18 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21 /* License for more details. */
22 /* */
23 /* You should have received a copy of the GNU Lesser General Public License */
24 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26 /* */
27 /* The copyright holder's institutional names and contributor's names may not */
28 /* be used to endorse or promote products derived from this software without */
29 /* specific prior written permission of the institution or contributor. */
30 /******************************************************************************/
31 
32 #include <sys/types.h>
33 #include <signal.h>
34 #include <cstdlib>
35 #ifdef WIN32
36 #include "XrdSys/XrdWin32.hh"
37 #endif
38 
39 #include "XrdSys/XrdSysError.hh"
40 
41 struct StreamInfo;
42 class XrdOucEnv;
43 class XrdOucString;
44 class XrdOucTList;
45 
47 {
48 public:
49 
50 // When creating a stream object, you may pass an optional error routing object.
51 // If you do so, error messages will be writen via the error object. Otherwise,
52 // errors will be returned quietly.
53 //
54  XrdOucStream(XrdSysError *erobj=0, const char *ifname=0,
55  XrdOucEnv *anEnv=0, const char *Pfx=0);
56 
57  ~XrdOucStream() {Close(); if (myInst) free(myInst);
58  if (varVal) delete [] varVal;
59  if (llBuff) free(llBuff);
60  }
61 
62 // Attach a file descriptor to an existing stream. Any curently associated
63 // stream is closed and detached. An optional buffer size can be specified.
64 // Zero is returned upon success, otherwise a -1 (use LastError to get rc).
65 //
66 int Attach(int FileDescriptor, int bsz=2047);
67 int AttachIO(int infd, int outfd, int bsz=2047);
68 
69 // Close the current stream and release the associated buffer.
70 //
71 void Close(int hold=0);
72 
73 // Detach a file descriptor from a stream. This should be called prior to
74 // close/delete when you are managing your own descriptors. Return the FD num.
75 //
76 int Detach() {int oldFD = FD; FD = FE = -1; return oldFD;}
77 
78 // Wait for an Exec() to finish and return the ending status. Use this
79 // function only when you need to find out the ending status of the command.
80 //
81 int Drain();
82 
83 // Display last valid line if variable substitution enabled. Fully formed
84 // input lines are displayed if 'set -v' was encountered (only when using
85 // the GetxxxWord() methods),
86 //
87 void Echo();
88 void Echo(bool capture);
89 
90 // Execute a command on a stream. Returns 0 upon success or -1 otherwise.
91 // Use LastError() to get the actual error code. Subsequent Get() calls
92 // will return the standard output of the executed command. If inrd=1 then
93 // standardin is redirected so that subqseuent Put() calls write to the
94 // process via standard in. When inrd=-1 then the current attached FD's are
95 // used to redirect STDIN and STDOUT of the child process. Standard error
96 // is handled as determined by the efd argument:
97 // efd < 0 -> How to handle the current stderr file decriptor:
98 // -1 The current stderr file decriptor is unchanged.
99 // Output of only stdout is to be captured by this stream.
100 // -2 Output of only stderr is to be captured by this stream.
101 // -3 Output of stdout and stderr is to be captured by this stream.
102 // efd = 0 -> The stderr file descriptor is set to the original logging FD
103 // efd > 0 -> The stderr file descriptor is set to the value of efd.
104 //
105 int Exec(const char *, int inrd=0, int efd=0);
106 int Exec( char **, int inrd=0, int efd=0);
107 
108 // Get the file descriptor number associated with a stream
109 //
110 int FDNum() {return FD;}
111 int FENum() {return FE;}
112 
113 // Flush any remaining output queued on an output stream.
114 //
115 void Flush() {fsync(FD); if (FE != FD) fsync(FE);}
116 
117 // Get the next record from a stream. Return null upon eof or error. Use
118 // LastError() to determine which condition occurred (an error code of 0
119 // indicates that end of file has been reached). Upon success, a pointer
120 // to the next record is returned. The record is terminated by a null char.
121 //
122 char *GetLine();
123 
124 // Get the next blank-delimited token in the record returned by Getline(). A
125 // null pointer is returned if no more tokens remain. Each token is terminated
126 // a null byte. Note that the record buffer is modified during processing. The
127 // first form returns simply a token pointer. The second form returns a token
128 // pointer and a pointer to the remainder of the line with no leading blanks.
129 // The lowcase argument, if 1, converts all letters to lower case in the token.
130 // RetToken() simply backups the token scanner one token. None of these
131 // methods perform variable substitution (see GetxxxWord() below).
132 //
133 char *GetToken(int lowcase=0);
134 char *GetToken(char **rest, int lowcase=0);
135 void RetToken();
136 
137 // Get the next word, ignoring any blank lines and comment lines (lines whose
138 // first non-blank is a pound sign). Words are returned until logical end of
139 // line is encountered at which time, a null is returned. A subsequent call
140 // will return the next word on the next logical line. A physical line may be
141 // continued by placing a back slash at it's end (i.e., last non-blank char).
142 // GetFirstWord() always makes sure that the first word of a logical line is
143 // returned (useful for start afresh after a mid-sentence error). GetRest()
144 // places the remining tokens in the supplied buffer; returning 0 if the
145 // buffer was too small. All of these methods perform variable substitution
146 // should an XrdOucEnv object be passed to the constructor.
147 //
148 char *GetFirstWord(int lowcase=0);
149 char *GetMyFirstWord(int lowcase=0);
150 int GetRest(char *theBuf, int Blen, int lowcase=0);
151 char *GetWord(int lowcase=0);
152 
153 // Indicate wether there is an active program attached to the stream
154 //
155 #ifndef WIN32
156 inline int isAlive() {return (child ? kill(child,0) == 0 : 0);}
157 #else
158 inline int isAlive() {return (child ? 1 : 0);}
159 #endif
160 
161 // Return last error code encountered.
162 //
163 inline int LastError() {int n = ecode; ecode = 0; return n;}
164 
165 // Return the last input line
166 //
167 char *LastLine() {return recp;}
168 
169 // Suppress echoing the previous line when the next line is fetched.
170 //
171 int noEcho() {llBok = 0; return 0;}
172 
173 // Write a record to a stream, if a length is not given, then the buffer must
174 // be null terminated and this defines the length (the null is not written).
175 //
176 int Put(const char *data, const int dlen);
177 inline int Put(const char *data) {return Put(data, strlen(data));}
178 
179 // Write record fragments to a stream. The list of fragment/length pairs ends
180 // when a null pointer is encountered.
181 //
182 int Put(const char *data[], const int dlen[]);
183 
184 // Insert a line into the stream buffer. This replaces anything that was there.
185 //
186 int PutLine(const char *data, int dlen=0);
187 
188 // Set the Env (returning the old Env). This is useful for suppressing
189 // substitutions for a while.
190 //
192  {XrdOucEnv *oldEnv = myEnv; myEnv = newEnv; return oldEnv;}
193 
194 // Set error routing
195 //
196 void SetEroute(XrdSysError *eroute) {Eroute = eroute;}
197 
198 // A 0 indicates that tabs in the stream should be converted to spaces.
199 // A 1 inducates that tabs should be left alone (the default).
200 //
201 void Tabs(int x=1) {notabs = !x;}
202 
203 // Wait for inbound data to arrive. The argument is the max number of millisec
204 // to wait (-1 means wait forever). Returns 0 if data is present. Otherwise,
205 // -1 indicates that the connection timed out, a positive value indicates an
206 // error and the value is the errno describing the error.
207 //
208 int Wait4Data(int msMax=-1);
209 
210 /******************************************************************************/
211 
212 // The following methods are norally used only during initial configuration
213 // to capture the actual configuration being used by each component.
214 
215 // Capture a message (typically informational before the start of file
216 // processing); which is added as a comment. Pass a vector of string whose
217 // last element is 0.
218 //
219 static void Capture(const char** cVec=0, bool linefeed=true);
220 
221 // Set the capture string object. A value of nil turns off capturing. The
222 // current capture string pointer is returned.
223 //
224 static
226 
227 // Return the current capture string object.
228 //
229 static
231 
232 /******************************************************************************/
233 
234 private:
235  void add2CFG(const char *data, bool isCMT=false);
236  char *add2llB(char *tok, int reset=0);
237  bool docont();
238  bool docont( const char *path, XrdOucTList *tlP);
239  bool docontD(const char *path, XrdOucTList *tlP);
240  bool docontF(const char *path, bool noentok=false);
241  char *doelse();
242  char *doif();
243  bool Echo(int ec, const char *t1, const char *t2=0, const char *t3=0);
244  int getValue(const char *path, char *vbuff, int vbsz);
245  int isSet(char *var);
246  char *vSubs(char *Var);
247  int xMsg(const char *txt1, const char *txt2=0, const char *txt3=0);
248 
249 static const int maxVLen = 512;
250 static const int llBsz = 1024;
251 
252  int FD;
253  int FE;
254  int bsize;
255  int bleft;
256  char *buff;
257  char *bnext;
258  char *recp;
259  char *token;
260  int flags;
261  pid_t child;
262  int ecode;
263  int notabs;
264  int xcont;
265  int xline;
266  char *myInst;
267  StreamInfo *myInfo; // ABI compatible change!
268  char *myRsv1;
269  char *myRsv2;
270  XrdSysError *Eroute;
271  XrdOucEnv *myEnv;
272  char *varVal;
273  const char *llPrefix;
274  char *llBuff;
275  char *llBcur;
276  int llBleft;
277  char Verbose;
278  char sawif;
279  char skpel;
280  char llBok;
281 static
282 XrdOucString *theCFG;
283 };
284 #endif
int fsync(int fildes)
XrdOucStream(XrdSysError *erobj=0, const char *ifname=0, XrdOucEnv *anEnv=0, const char *Pfx=0)
char * GetMyFirstWord(int lowcase=0)
int PutLine(const char *data, int dlen=0)
static XrdOucString * Capture()
char * GetLine()
char * LastLine()
char * GetFirstWord(int lowcase=0)
char * GetWord(int lowcase=0)
int Put(const char *data)
int Attach(int FileDescriptor, int bsz=2047)
int AttachIO(int infd, int outfd, int bsz=2047)
int Put(const char *data, const int dlen)
int Exec(const char *, int inrd=0, int efd=0)
int Wait4Data(int msMax=-1)
void Close(int hold=0)
void SetEroute(XrdSysError *eroute)
XrdOucEnv * SetEnv(XrdOucEnv *newEnv)
void Tabs(int x=1)
char * GetToken(int lowcase=0)
int GetRest(char *theBuf, int Blen, int lowcase=0)