ExternalDataSource.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00015 #define _GNU_SOURCE 1 // for ::getline
00016 
00017 #include <signal.h>
00018 #include <errno.h>
00019 #include <unistd.h>
00020 #include <sys/wait.h>
00021 #include <fcntl.h>
00022 #include <iostream>
00023 
00024 #include <string>
00025 
00026 #include "zypp/base/Logger.h"
00027 #include "zypp/base/ExternalDataSource.h"
00028 
00029 using namespace std;
00030 
00031 namespace zypp {
00032   namespace externalprogram {
00033 
00034     ExternalDataSource::ExternalDataSource (FILE *ifile, FILE *ofile)
00035       : inputfile (ifile),
00036         outputfile (ofile),
00037         linebuffer (0),
00038         linebuffer_size (0)
00039     {
00040     }
00041     
00042     
00043     ExternalDataSource::~ExternalDataSource ()
00044     {
00045       if (linebuffer)
00046         free (linebuffer);
00047       close ();
00048     }
00049     
00050     
00051     bool
00052     ExternalDataSource::send (const char *buffer, size_t length)
00053     {
00054       if (outputfile) {
00055         bool success = fwrite (buffer, length, 1, outputfile) != 0;
00056         fflush (outputfile);
00057         return success;
00058       }
00059       else
00060         return false;
00061     }
00062     
00063     
00064     bool
00065     ExternalDataSource::send (string s)
00066     {
00067       DBG << "send (" << s << ")";
00068       return send(s.data(), s.length());
00069     }
00070     
00071     
00072     string
00073     ExternalDataSource::receiveUpto (char c)
00074     {
00075       if (inputfile)
00076       {
00077         string result;
00078         while (true)
00079         {
00080             const size_t length = 4096;
00081             char buffer[length];
00082             char *writepointer = buffer;
00083             size_t readbytes = 0;
00084             int readc = -1;
00085     
00086             while (!feof(inputfile) && readbytes < length)
00087             {
00088                 readc = fgetc(inputfile);
00089                 if (readc == EOF) break;
00090                 *writepointer++ = (char) readc;
00091                 if ((char) readc == c) break;
00092                 readbytes++;
00093             }
00094             *writepointer = 0;
00095             result += buffer;
00096             if (readbytes < length || (char) readc == c) break;
00097     
00098         }
00099         return result;
00100       }
00101     
00102       else return "";
00103     }
00104     
00105     
00106     size_t
00107     ExternalDataSource::receive (char *buffer, size_t length)
00108     {
00109       if (inputfile)
00110         return fread (buffer, 1, length, inputfile);
00111       else
00112         return 0;
00113     }
00114     
00115     void ExternalDataSource::setBlocking(bool mode)
00116     {
00117       if(!inputfile) return;
00118     
00119       int fd = ::fileno(inputfile);
00120     
00121       if(fd == -1)
00122         { ERR << strerror(errno) << endl; return; }
00123     
00124       int flags = ::fcntl(fd,F_GETFL);
00125     
00126       if(flags == -1)
00127         { ERR << strerror(errno) << endl; return; }
00128     
00129       if(!mode)
00130         flags = flags | O_NONBLOCK;
00131       else if(flags & O_NONBLOCK)
00132         flags = flags ^ O_NONBLOCK;
00133     
00134       flags = ::fcntl(fd,F_SETFL,flags);
00135     
00136       if(flags == -1)
00137         { ERR << strerror(errno) << endl; return; }
00138     }
00139     
00140     string
00141     ExternalDataSource::receiveLine()
00142     {
00143       if (inputfile)
00144       {
00145         ssize_t nread = getline (&linebuffer, &linebuffer_size, inputfile);
00146         if (nread == -1)
00147             return "";
00148         else
00149             return string (linebuffer, nread);
00150       }
00151       else
00152         return "";
00153     }
00154     
00155     
00156     int
00157     ExternalDataSource::close ()
00158     {
00159       if (inputfile && inputfile != outputfile)
00160         fclose (inputfile);
00161       if (outputfile)
00162         fclose (outputfile);
00163       inputfile = 0;
00164       outputfile = 0;
00165       return 0;
00166     }
00167     
00168 
00169   } // namespace externalprogram
00170 } // namespace zypp
00171 

Generated on Thu Jul 6 00:07:20 2006 for zypp by  doxygen 1.4.6