Imported Upstream version 17.25.4
[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 #include <sstream>
23 #include <string>
24
25 #include <zypp/base/Logger.h>
26 #include <zypp/base/ExternalDataSource.h>
27 #include <zypp/AutoDispose.h>
28
29 using std::endl;
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     std::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 std::string();
88     }
89
90     std::string ExternalDataSource::receiveUpto( char c, io::timeout_type timeout )
91     {
92       const auto &received = io::receiveUpto( inputFile(), c, timeout );
93
94       if ( received.first == io::Timeout )
95         ZYPP_THROW( io::TimeoutException() );
96
97       return received.second;
98     }
99
100     size_t
101     ExternalDataSource::receive( char *buffer, size_t length )
102     {
103       if ( inputfile )
104         return fread( buffer, 1, length, inputfile );
105       else
106         return 0;
107     }
108
109     void ExternalDataSource::setBlocking( bool mode )
110     {
111       io::setFILEBlocking( inputfile, mode );
112     }
113
114     std::string
115     ExternalDataSource::receiveLine()
116     {
117       if ( inputfile )
118       {
119         ssize_t nread = getline( &linebuffer, &linebuffer_size, inputfile );
120         if ( nread == -1 )
121             return "";
122         else
123             return std::string( linebuffer, nread );
124       }
125       else
126         return "";
127     }
128
129     std::string ExternalDataSource::receiveLine( io::timeout_type timeout )
130     {
131       return receiveUpto( '\n', timeout );
132     }
133
134     int
135     ExternalDataSource::close()
136     {
137       if ( inputfile && inputfile != outputfile )
138         fclose( inputfile );
139       if ( outputfile )
140         fclose( outputfile );
141       inputfile = 0;
142       outputfile = 0;
143       return 0;
144     }
145
146   } // namespace externalprogram
147 } // namespace zypp
148