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