00001 #ifndef __OOUC_STREAM__ 00002 #define __OOUC_STREAM__ 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d O u c S t r e a m . h h */ 00006 /* */ 00007 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */ 00008 /* All Rights Reserved. See XrdInfo.cc for complete License Terms */ 00009 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00010 /* DE-AC03-76-SFO0515 with the Deprtment of Energy */ 00011 /******************************************************************************/ 00012 00013 // $Id: XrdOucStream.hh 32231 2010-02-05 18:24:46Z ganis $ 00014 00015 #include <sys/types.h> 00016 #include <signal.h> 00017 #include <stdlib.h> 00018 #ifdef WIN32 00019 #include "XrdSys/XrdWin32.hh" 00020 #endif 00021 00022 #include "XrdSys/XrdSysError.hh" 00023 00024 class XrdOucEnv; 00025 00026 class XrdOucStream 00027 { 00028 public: 00029 00030 // When creating a stream object, you may pass an optional error routing object. 00031 // If you do so, error messages will be writen via the error object. Otherwise, 00032 // errors will be returned quietly. 00033 // 00034 XrdOucStream(XrdSysError *erobj=0, const char *ifname=0, 00035 XrdOucEnv *anEnv=0, const char *Pfx=0); 00036 00037 ~XrdOucStream() {Close(); if (myInst) free(myInst); 00038 if (varVal) delete [] varVal; 00039 if (llBuff) free(llBuff); 00040 } 00041 00042 // Attach a file descriptor to an existing stream. Any curently associated 00043 // stream is closed and detached. An optional buffer size can be specified. 00044 // Zero is returned upon success, otherwise a -1 (use LastError to get rc). 00045 // 00046 int Attach(int FileDescriptor, int bsz=2047); 00047 int AttachIO(int infd, int outfd, int bsz=2047); 00048 00049 // Close the current stream and release the associated buffer. 00050 // 00051 void Close(int hold=0); 00052 00053 // Detach a file descriptor from a stream. This should be called prior to 00054 // close/delete when you are managing your own descriptors. Return the FD num. 00055 // 00056 int Detach() {int oldFD = FD; FD = FE = -1; return oldFD;} 00057 00058 // Wait for an Exec() to finish and return the ending status. Use this 00059 // function only when you need to find out the ending status of the command. 00060 // 00061 int Drain(); 00062 00063 // Display last valid line if variable substitution enabled. Fully formed 00064 // input lines are displayed if 'set -v' was encountered (only when using 00065 // the GetxxxWord() methods), 00066 // 00067 void Echo(); 00068 00069 // Execute a command on a stream. Returns 0 upon success or -1 otherwise. 00070 // Use LastError() to get the actual error code. Subsequent Get() calls 00071 // will return the standard output of the executed command. If inrd=1 then 00072 // standardin is redirected so that subqseuent Put() calls write to the 00073 // process via standard in. When inrd=-1 then the current attached FD's are 00074 // used to redirect STDIN and STDOUT of the child process. Standard error 00075 // is handled as determined by the efd argument: 00076 // efd < 0 -> The current stderr file decriptor is unchanged. 00077 // efd = 0 -> The stderr file descriptor is set to the original logging FD 00078 // efd > 0 -> The stderr file descriptor is set to the value of efd. 00079 // 00080 int Exec(const char *, int inrd=0, int efd=0); 00081 int Exec( char **, int inrd=0, int efd=0); 00082 00083 // Get the file descriptor number associated with a stream 00084 // 00085 int FDNum() {return FD;} 00086 int FENum() {return FE;} 00087 00088 // Flush any remaining output queued on an output stream. 00089 // 00090 void Flush() {fsync(FD); if (FE != FD) fsync(FE);} 00091 00092 // Get the next record from a stream. Return null upon eof or error. Use 00093 // LastError() to determine which condition occurred (an error code of 0 00094 // indicates that end of file has been reached). Upon success, a pointer 00095 // to the next record is returned. The record is terminated by a null char. 00096 // 00097 char *GetLine(); 00098 00099 // Get the next blank-delimited token in the record returned by Getline(). A 00100 // null pointer is returned if no more tokens remain. Each token is terminated 00101 // a null byte. Note that the record buffer is modified during processing. The 00102 // first form returns simply a token pointer. The second form returns a token 00103 // pointer and a pointer to the remainder of the line with no leading blanks. 00104 // The lowcase argument, if 1, converts all letters to lower case in the token. 00105 // RetToken() simply backups the token scanner one token. None of these 00106 // methods perform variable substitution (see GetxxxWord() below). 00107 // 00108 char *GetToken(int lowcase=0); 00109 char *GetToken(char **rest, int lowcase=0); 00110 void RetToken(); 00111 00112 // Get the next word, ignoring any blank lines and comment lines (lines whose 00113 // first non-blank is a pound sign). Words are returned until logical end of 00114 // line is encountered at which time, a null is returned. A subsequent call 00115 // will return the next word on the next logical line. A physical line may be 00116 // continued by placing a back slash at it's end (i.e., last non-blank char). 00117 // GetFirstWord() always makes sure that the first word of a logical line is 00118 // returned (useful for start afresh after a mid-sentence error). GetRest() 00119 // places the remining tokens in the supplied buffer; returning 0 if the 00120 // buffer was too small. All of these methods perform variable substitution 00121 // should an XrdOucEnv object be passed to the constructor. 00122 // 00123 char *GetFirstWord(int lowcase=0); 00124 char *GetMyFirstWord(int lowcase=0); 00125 int GetRest(char *theBuf, int Blen, int lowcase=0); 00126 char *GetWord(int lowcase=0); 00127 00128 // Indicate wether there is an active program attached to the stream 00129 // 00130 #ifndef WIN32 00131 inline int isAlive() {return (child ? kill(child,0) == 0 : 0);} 00132 #else 00133 inline int isAlive() {return (child ? 1 : 0);} 00134 #endif 00135 00136 // Return last error code encountered. 00137 // 00138 inline int LastError() {int n = ecode; ecode = 0; return n;} 00139 00140 // Return the last input line 00141 // 00142 char *LastLine() {return recp;} 00143 00144 // Suppress echoing the previous line when the next line is fetched. 00145 // 00146 int noEcho() {llBok = 0; return 0;} 00147 00148 // Write a record to a stream, if a length is not given, then the buffer must 00149 // be null terminated and this defines the length (the null is not written). 00150 // 00151 int Put(const char *data, const int dlen); 00152 inline int Put(const char *data) {return Put(data, strlen(data));} 00153 00154 // Write record fragments to a stream. The list of fragment/length pairs ends 00155 // when a null pointer is encountered. 00156 // 00157 int Put(const char *data[], const int dlen[]); 00158 00159 // Set the Env (returning the old Env). This is useful for suppressing 00160 // substitutions for a while. 00161 // 00162 XrdOucEnv *SetEnv(XrdOucEnv *newEnv) 00163 {XrdOucEnv *oldEnv = myEnv; myEnv = newEnv; return oldEnv;} 00164 00165 // Set error routing 00166 // 00167 void SetEroute(XrdSysError *eroute) {Eroute = eroute;} 00168 00169 // A 0 indicates that tabs in the stream should be converted to spaces. 00170 // A 1 inducates that tabs should be left alone (the default). 00171 // 00172 void Tabs(int x=1) {notabs = !x;} 00173 00174 // Wait for inbound data to arrive. The argument is the max number of millisec 00175 // to wait (-1 means wait forever). Returns 0 if data is present. Otherwise, 00176 // -1 indicates that the connection timed out, a positive value indicates an 00177 // error and the value is the errno describing the error. 00178 // 00179 int Wait4Data(int msMax=-1); 00180 00181 /******************************************************************************/ 00182 00183 private: 00184 char *add2llB(char *tok, int reset=0); 00185 char *doelse(); 00186 char *doif(); 00187 int isSet(char *var); 00188 char *vSubs(char *Var); 00189 int xMsg(const char *txt1, const char *txt2=0, const char *txt3=0); 00190 00191 static const int maxVLen = 512; 00192 static const int llBsz = 1024; 00193 00194 int FD; 00195 int FE; 00196 int bsize; 00197 int bleft; 00198 char *buff; 00199 char *bnext; 00200 char *recp; 00201 char *token; 00202 int flags; 00203 pid_t child; 00204 int ecode; 00205 int notabs; 00206 int xcont; 00207 int xline; 00208 char *myInst; 00209 char *myHost; 00210 char *myName; 00211 char *myExec; 00212 XrdSysError *Eroute; 00213 XrdOucEnv *myEnv; 00214 char *varVal; 00215 const char *llPrefix; 00216 char *llBuff; 00217 char *llBcur; 00218 int llBleft; 00219 char Verbose; 00220 char sawif; 00221 char skpel; 00222 char llBok; 00223 }; 00224 #endif