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