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 <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 }
00171 }
00172