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

Generated on Sat Sep 5 12:05:05 2009 for zypp by  doxygen 1.4.6