Line data Source code
1 : // Copyright (c) 2013-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/eventdispatcher
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // self
21 : //
22 : #include <cppprocess/io_data_pipe.h>
23 :
24 :
25 : // last include
26 : //
27 : #include <snapdev/poison.h>
28 :
29 :
30 :
31 : namespace cppprocess
32 : {
33 :
34 :
35 :
36 : /** \brief Initialize the IO data pipe.
37 : *
38 : * This constructor initialize the pipe as an input pipe.
39 : *
40 : * Once created, call the add_input() to add data to the pipe.
41 : */
42 3 : io_data_pipe::io_data_pipe()
43 3 : : io_pipe(IO_FLAG_INPUT)
44 : {
45 3 : }
46 :
47 :
48 : /** \brief The input to be sent to stdin.
49 : *
50 : * Add the input data to be written to the stdin pipe. Note that the input
51 : * cannot be modified once the run() command was called unless the mode
52 : * is PROCESS_MODE_INOUT_INTERACTIVE.
53 : *
54 : * Note that in all case, calling this function multiple times adds more
55 : * data to the input. It does not erase what was added before. The thread
56 : * may eat some of the input in which case it gets removed from the internal
57 : * variable.
58 : *
59 : * \note
60 : * The function is safe and adding new input from the output thread
61 : * (which happens in interactive mode) is protected.
62 : *
63 : * \param[in] input The input of the process (stdin).
64 : *
65 : * \sa add_input(buffer_t const & input)
66 : */
67 3 : void io_data_pipe::add_input(std::string const & input)
68 : {
69 : // this is additive!
70 : //
71 3 : add_input(buffer_t(input.begin(), input.end()));
72 3 : }
73 :
74 :
75 : /** \brief Binary data to be sent to stdin.
76 : *
77 : * When the input data is binary, use the QByteArray instead of a std::string
78 : * so you are sure it gets properly added.
79 : *
80 : * Calling this function multiple times appends the new data to the
81 : * existing data.
82 : *
83 : * Please, see the other set_input() function for additional information.
84 : *
85 : * \note
86 : * When sending a std::string, remember that these are converted to UTF-8
87 : * which is not compatible with purely binary data (i.e. UTF-8, for example,
88 : * does not allow for 0xFE and 0xFF.)
89 : *
90 : * \param[in] input The input of the process (stdin).
91 : *
92 : * \sa add_input(std::string const & input)
93 : */
94 3 : void io_data_pipe::add_input(buffer_t const & input)
95 : {
96 : // this is additive!
97 : //
98 3 : f_input.insert(f_input.end(), input.begin(), input.end());
99 3 : }
100 :
101 :
102 : /** \brief Retrieve a copy of the input buffer as a string.
103 : *
104 : * This function returns the contents of the input buffer as a string.
105 : *
106 : * \return A copy of the input.
107 : *
108 : * \sa get_binary_input()
109 : */
110 2 : std::string io_data_pipe::get_input(bool reset) const
111 : {
112 2 : std::string input(reinterpret_cast<char const *>(f_input.data()), f_input.size());
113 2 : if(reset)
114 : {
115 0 : const_cast<io_data_pipe *>(this)->f_input.clear();
116 : }
117 2 : return input;
118 : }
119 :
120 :
121 : /** \brief Retrieve a copy of the input buffer.
122 : *
123 : * This function returns the contents of the input buffer. In most cases,
124 : * you'll never need this function (you should know what you add to your
125 : * command input).
126 : *
127 : * \return A copy of the input.
128 : *
129 : * \sa get_input()
130 : */
131 2 : buffer_t io_data_pipe::get_binary_input(bool reset) const
132 : {
133 2 : buffer_t const input(f_input);
134 2 : if(reset)
135 : {
136 0 : const_cast<io_data_pipe *>(this)->f_input.clear();
137 : }
138 2 : return input;
139 : }
140 :
141 :
142 : /** \brief Check whether the pipe is a writer or not.
143 : *
144 : * The pipe is a writer as long as it includes input data. Once the pipe
145 : * is empty, the done function will be called (after that happens, you
146 : * can't add data anymore).
147 : *
148 : * \return true until all the input data was sent to the process.
149 : */
150 9 : bool io_data_pipe::is_writer() const
151 : {
152 9 : return f_pos < f_input.size();
153 : }
154 :
155 :
156 : /** \brief Send some data to the process.
157 : *
158 : * This function writes the input data to the input pipe of the process.
159 : * The function writes as much data as posssible (i.e. as large as the
160 : * FIFO buffer supports) then returns.
161 : *
162 : * The function will be called as long as data can be pushed to the FIFO.
163 : * The communicator will know once there is more space available so this
164 : * function can write to the FIFO.
165 : */
166 3 : void io_data_pipe::process_write()
167 : {
168 3 : std::size_t const size(f_input.size() - f_pos);
169 3 : if(size > 0)
170 : {
171 3 : ssize_t const r(write(f_input.data() + f_pos, size));
172 3 : if(r > 0)
173 : {
174 3 : f_pos += r;
175 :
176 3 : if(f_pos >= f_input.size())
177 : {
178 3 : process_done(done_reason_t::DONE_REASON_EOF);
179 : }
180 : }
181 : }
182 3 : }
183 :
184 :
185 :
186 6 : } // namespace cppprocess
187 : // vim: ts=4 sw=4 et
|