2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
20 /***************************************************************************
21 inpipestream.cpp - C++ streambuffer wrapper
23 begin : Thu Dec 27 2001
24 copyright : (C) 2001 by Intra2net AG
25 ***************************************************************************/
36 #include "exception.hxx"
37 #include "pipestream.hxx"
39 /** @brief runs command and returns it's output as string
40 * @param command the full command with all parameters
41 * @param rescode struct containing the return code, if the program exited normally and so on
42 * @returns the output (stdout) of the called program
44 std::string capture_exec(const std::string& command, ExecResult &rescode)
48 bool exit_set = false;
49 int exit_status_waitpid;
51 // set the results to false until we are sure we have proper values
52 rescode.normal_exit = false;
53 rescode.terminated_by_signal = false;
58 inpipestream ips(command);
60 ips.store_exit_status(&exit_set, &exit_status_waitpid);
65 ips.read(buffer, sizeof(buffer));
66 output.append(buffer, ips.gcount());
70 // exit_status_waitpid only valid after destruction of the inpipestream
74 rescode.normal_exit = WIFEXITED(exit_status_waitpid);
75 if (rescode.normal_exit)
76 rescode.return_code = WEXITSTATUS(exit_status_waitpid);
78 rescode.terminated_by_signal = WIFSIGNALED(exit_status_waitpid);
79 if (rescode.terminated_by_signal)
80 rescode.signal = WTERMSIG(exit_status_waitpid);
83 catch (pipestream_error &e)
85 rescode.error_message = e.what();
91 inpipebuf::inpipebuf(const std::string& command)
96 pipe = popen (command.c_str(), "r");
98 throw EXCEPTION (pipestream_error, "can't open program or permission denied");
101 setg (&buffer, &buffer, &buffer);
104 inpipebuf::~inpipebuf()
107 int pclose_exit = pclose (pipe);
109 if (exit_status && pclose_exit != -1)
113 *exit_status = pclose_exit;
120 /** note: exit status only available after destruction */
121 void inpipebuf::store_exit_status(bool *_status_set, int *_exit_status)
123 status_set = _status_set;
124 exit_status = _exit_status;
127 inpipebuf::int_type inpipebuf::underflow()
129 if (gptr() < egptr())
130 return traits_type::to_int_type(*gptr());
132 buffer = fgetc (pipe);
139 setg (&buffer, &buffer, &buffer+sizeof(char));
141 return traits_type::to_int_type(*gptr());
144 outpipebuf::outpipebuf(const std::string& command)
149 pipe = popen (command.c_str(), "w");
151 throw EXCEPTION (pipestream_error, "can't open program or permission denied");
154 outpipebuf::~outpipebuf()
157 int pclose_exit = pclose (pipe);
159 if (exit_status && pclose_exit != -1)
163 *exit_status = pclose_exit;
170 /** note: exit status only available after destruction */
171 void outpipebuf::store_exit_status(bool *_status_set, int *_exit_status)
173 status_set = _status_set;
174 exit_status = _exit_status;
177 outpipebuf::int_type outpipebuf::overflow(int_type c)
181 if (fputc(c,pipe)==EOF)
187 std::streamsize outpipebuf::xsputn(const char* s, std::streamsize num)
189 return fwrite(s,num,1,pipe);