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