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 /* All Rights Reserved. See XrdInfo.cc for complete License Terms */
9 /* Produced by Andrew Hanushevsky for Stanford University under contract */
10 /* DE-AC03-76-SFO0515 with the Deprtment of Energy */
11 /******************************************************************************/
12 
13 #include <sys/types.h>
14 #include <signal.h>
15 #include <stdlib.h>
16 #ifdef WIN32
17 #include "XrdSys/XrdWin32.hh"
18 #endif
19 
20 #include "XrdSys/XrdSysError.hh"
21 
22 class XrdOucEnv;
23 
25 {
26 public:
27 
28 // When creating a stream object, you may pass an optional error routing object.
29 // If you do so, error messages will be writen via the error object. Otherwise,
30 // errors will be returned quietly.
31 //
32  XrdOucStream(XrdSysError *erobj=0, const char *ifname=0,
33  XrdOucEnv *anEnv=0, const char *Pfx=0);
34 
35  ~XrdOucStream() {Close(); if (myInst) free(myInst);
36  if (varVal) delete [] varVal;
37  if (llBuff) free(llBuff);
38  }
39 
40 // Attach a file descriptor to an existing stream. Any curently associated
41 // stream is closed and detached. An optional buffer size can be specified.
42 // Zero is returned upon success, otherwise a -1 (use LastError to get rc).
43 //
44 int Attach(int FileDescriptor, int bsz=2047);
45 int AttachIO(int infd, int outfd, int bsz=2047);
46 
47 // Close the current stream and release the associated buffer.
48 //
49 void Close(int hold=0);
50 
51 // Detach a file descriptor from a stream. This should be called prior to
52 // close/delete when you are managing your own descriptors. Return the FD num.
53 //
54 int Detach() {int oldFD = FD; FD = FE = -1; return oldFD;}
55 
56 // Wait for an Exec() to finish and return the ending status. Use this
57 // function only when you need to find out the ending status of the command.
58 //
59 int Drain();
60 
61 // Display last valid line if variable substitution enabled. Fully formed
62 // input lines are displayed if 'set -v' was encountered (only when using
63 // the GetxxxWord() methods),
64 //
65 void Echo();
66 
67 // Execute a command on a stream. Returns 0 upon success or -1 otherwise.
68 // Use LastError() to get the actual error code. Subsequent Get() calls
69 // will return the standard output of the executed command. If inrd=1 then
70 // standardin is redirected so that subqseuent Put() calls write to the
71 // process via standard in. When inrd=-1 then the current attached FD's are
72 // used to redirect STDIN and STDOUT of the child process. Standard error
73 // is handled as determined by the efd argument:
74 // efd < 0 -> The current stderr file decriptor is unchanged.
75 // efd = 0 -> The stderr file descriptor is set to the original logging FD
76 // efd > 0 -> The stderr file descriptor is set to the value of efd.
77 //
78 int Exec(const char *, int inrd=0, int efd=0);
79 int Exec( char **, int inrd=0, int efd=0);
80 
81 // Get the file descriptor number associated with a stream
82 //
83 int FDNum() {return FD;}
84 int FENum() {return FE;}
85 
86 // Flush any remaining output queued on an output stream.
87 //
88 void Flush() {fsync(FD); if (FE != FD) fsync(FE);}
89 
90 // Get the next record from a stream. Return null upon eof or error. Use
91 // LastError() to determine which condition occurred (an error code of 0
92 // indicates that end of file has been reached). Upon success, a pointer
93 // to the next record is returned. The record is terminated by a null char.
94 //
95 char *GetLine();
96 
97 // Get the next blank-delimited token in the record returned by Getline(). A
98 // null pointer is returned if no more tokens remain. Each token is terminated
99 // a null byte. Note that the record buffer is modified during processing. The
100 // first form returns simply a token pointer. The second form returns a token
101 // pointer and a pointer to the remainder of the line with no leading blanks.
102 // The lowcase argument, if 1, converts all letters to lower case in the token.
103 // RetToken() simply backups the token scanner one token. None of these
104 // methods perform variable substitution (see GetxxxWord() below).
105 //
106 char *GetToken(int lowcase=0);
107 char *GetToken(char **rest, int lowcase=0);
108 void RetToken();
109 
110 // Get the next word, ignoring any blank lines and comment lines (lines whose
111 // first non-blank is a pound sign). Words are returned until logical end of
112 // line is encountered at which time, a null is returned. A subsequent call
113 // will return the next word on the next logical line. A physical line may be
114 // continued by placing a back slash at it's end (i.e., last non-blank char).
115 // GetFirstWord() always makes sure that the first word of a logical line is
116 // returned (useful for start afresh after a mid-sentence error). GetRest()
117 // places the remining tokens in the supplied buffer; returning 0 if the
118 // buffer was too small. All of these methods perform variable substitution
119 // should an XrdOucEnv object be passed to the constructor.
120 //
121 char *GetFirstWord(int lowcase=0);
122 char *GetMyFirstWord(int lowcase=0);
123 int GetRest(char *theBuf, int Blen, int lowcase=0);
124 char *GetWord(int lowcase=0);
125 
126 // Indicate wether there is an active program attached to the stream
127 //
128 #ifndef WIN32
129 inline int isAlive() {return (child ? kill(child,0) == 0 : 0);}
130 #else
131 inline int isAlive() {return (child ? 1 : 0);}
132 #endif
133 
134 // Return last error code encountered.
135 //
136 inline int LastError() {int n = ecode; ecode = 0; return n;}
137 
138 // Return the last input line
139 //
140 char *LastLine() {return recp;}
141 
142 // Suppress echoing the previous line when the next line is fetched.
143 //
144 int noEcho() {llBok = 0; return 0;}
145 
146 // Write a record to a stream, if a length is not given, then the buffer must
147 // be null terminated and this defines the length (the null is not written).
148 //
149 int Put(const char *data, const int dlen);
150 inline int Put(const char *data) {return Put(data, strlen(data));}
151 
152 // Write record fragments to a stream. The list of fragment/length pairs ends
153 // when a null pointer is encountered.
154 //
155 int Put(const char *data[], const int dlen[]);
156 
157 // Insert a line into the stream buffer. This replaces anything that was there.
158 //
159 int PutLine(const char *data, int dlen=0);
160 
161 // Set the Env (returning the old Env). This is useful for suppressing
162 // substitutions for a while.
163 //
165  {XrdOucEnv *oldEnv = myEnv; myEnv = newEnv; return oldEnv;}
166 
167 // Set error routing
168 //
169 void SetEroute(XrdSysError *eroute) {Eroute = eroute;}
170 
171 // A 0 indicates that tabs in the stream should be converted to spaces.
172 // A 1 inducates that tabs should be left alone (the default).
173 //
174 void Tabs(int x=1) {notabs = !x;}
175 
176 // Wait for inbound data to arrive. The argument is the max number of millisec
177 // to wait (-1 means wait forever). Returns 0 if data is present. Otherwise,
178 // -1 indicates that the connection timed out, a positive value indicates an
179 // error and the value is the errno describing the error.
180 //
181 int Wait4Data(int msMax=-1);
182 
183 /******************************************************************************/
184 
185 private:
186  char *add2llB(char *tok, int reset=0);
187  char *doelse();
188  char *doif();
189  int isSet(char *var);
190  char *vSubs(char *Var);
191  int xMsg(const char *txt1, const char *txt2=0, const char *txt3=0);
192 
193 static const int maxVLen = 512;
194 static const int llBsz = 1024;
195 
196  int FD;
197  int FE;
198  int bsize;
199  int bleft;
200  char *buff;
201  char *bnext;
202  char *recp;
203  char *token;
204  int flags;
205  pid_t child;
206  int ecode;
207  int notabs;
208  int xcont;
209  int xline;
210  char *myInst;
211  char *myHost;
212  char *myName;
213  char *myExec;
216  char *varVal;
217  const char *llPrefix;
218  char *llBuff;
219  char *llBcur;
220  int llBleft;
221  char Verbose;
222  char sawif;
223  char skpel;
224  char llBok;
225 };
226 #endif