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