ExternalDataSource.cc
Go to the documentation of this file.00001
00002
00003
00004
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 }
00172 }
00173