fixup Fix to build with libxml 2.12.x (fixes #505)
[platform/upstream/libzypp.git] / zypp / base / ExternalDataSource.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/ExternalDataSource.cc
10  */
11
12 #define _GNU_SOURCE 1 // for ::getline
13
14 #include <signal.h>
15 #include <errno.h>
16 #include <unistd.h>
17 #include <sys/wait.h>
18 #include <fcntl.h>
19 #include <iostream>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <sstream>
24 #include <string>
25
26 #include "zypp/base/Logger.h"
27 #include "zypp/base/ExternalDataSource.h"
28
29 using namespace std;
30
31 namespace zypp {
32   namespace externalprogram {
33
34     ExternalDataSource::ExternalDataSource (FILE *ifile, FILE *ofile)
35       : inputfile (ifile),
36         outputfile (ofile),
37         linebuffer (0),
38         linebuffer_size (0)
39     {
40     }
41
42
43     ExternalDataSource::~ExternalDataSource ()
44     {
45       if (linebuffer)
46         free (linebuffer);
47       close ();
48     }
49
50
51     bool
52     ExternalDataSource::send (const char *buffer, size_t length)
53     {
54       if (outputfile) {
55         bool success = fwrite (buffer, length, 1, outputfile) != 0;
56         fflush (outputfile);
57         return success;
58       }
59       else
60         return false;
61     }
62
63
64     bool
65     ExternalDataSource::send (std::string s)
66     {
67       DBG << "send (" << s << ")";
68       return send(s.data(), s.length());
69     }
70
71
72     string
73     ExternalDataSource::receiveUpto (char c)
74     {
75       if (inputfile && !feof(inputfile))
76       {
77         std::ostringstream datas;
78          while ( true )
79          {
80            int readc = fgetc(inputfile);
81            if (readc == EOF) break;
82            datas << (char)readc;
83            if ((char)readc == c) break;
84          }
85          return datas.str();
86       }
87       return string();
88     }
89
90
91     size_t
92     ExternalDataSource::receive (char *buffer, size_t length)
93     {
94       if (inputfile)
95         return fread (buffer, 1, length, inputfile);
96       else
97         return 0;
98     }
99
100     void ExternalDataSource::setBlocking(bool mode)
101     {
102       if(!inputfile) return;
103
104       int fd = ::fileno(inputfile);
105
106       if(fd == -1)
107         { ERR << strerror(errno) << endl; return; }
108
109       int flags = ::fcntl(fd,F_GETFL);
110
111       if(flags == -1)
112         { ERR << strerror(errno) << endl; return; }
113
114       if(!mode)
115         flags = flags | O_NONBLOCK;
116       else if(flags & O_NONBLOCK)
117         flags = flags ^ O_NONBLOCK;
118
119       flags = ::fcntl(fd,F_SETFL,flags);
120
121       if(flags == -1)
122         { ERR << strerror(errno) << endl; return; }
123     }
124
125     string
126     ExternalDataSource::receiveLine()
127     {
128       if (inputfile)
129       {
130         ssize_t nread = getline (&linebuffer, &linebuffer_size, inputfile);
131         if (nread == -1)
132             return "";
133         else
134             return string (linebuffer, nread);
135       }
136       else
137         return "";
138     }
139
140
141     int
142     ExternalDataSource::close ()
143     {
144       if (inputfile && inputfile != outputfile)
145         fclose (inputfile);
146       if (outputfile)
147         fclose (outputfile);
148       inputfile = 0;
149       outputfile = 0;
150       return 0;
151     }
152
153
154   } // namespace externalprogram
155 } // namespace zypp
156