2 /******************************************************************************
3 * MODULE : qt_pipe_link.cpp
4 * DESCRIPTION: TeXmacs links by pipes
5 * COPYRIGHT : (C) 2000 Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
14 #if defined (QTTEXMACS) && (defined (__MINGW__) || defined (__MINGW32__) || defined (QTPIPES))
16 #include "tm_link.hpp"
17 #include "QTMPipeLink.hpp"
18 #include "hashset.hpp"
19 #include "iterator.hpp"
22 #include <sys/types.h>
24 #if defined(__MINGW__) || defined(__MINGW32__)
26 # include <sys/wait.h>
29 hashset
<pointer
> pipe_link_set
;
31 /******************************************************************************
32 * Definition of qt_pipe_link_rep class
33 ******************************************************************************/
35 struct qt_pipe_link_rep
: tm_link_rep
{
39 qt_pipe_link_rep (string cmd
);
43 void write (string s
, int channel
);
44 string
& watch (int channel
);
45 string
read (int channel
);
46 void listen (int msecs
);
47 bool is_readable (int channel
);
50 void feed (int channel
);
53 qt_pipe_link_rep::qt_pipe_link_rep (string cmd
) : PipeLink (cmd
) {
54 PipeLink
.feed_cmd
= &feed_cmd
;
55 pipe_link_set
->insert ((pointer
) this);
59 qt_pipe_link_rep::~qt_pipe_link_rep () {
61 pipe_link_set
->remove ((pointer
) this);
64 /******************************************************************************
65 * Routines for qt_pipe_links
66 ******************************************************************************/
69 qt_pipe_link_rep::start () {
70 if (alive
) return "busy";
71 if (DEBUG_AUTO
) cerr
<< "TeXmacs] Launching '" << PipeLink
.cmd
<< "'\n";
72 if (! PipeLink
.launchCmd ()) {
73 if (DEBUG_AUTO
) cerr
<< "TeXmacs] Error: cannot start '" << PipeLink
.cmd
<< "'\n";
74 return "Error: cannot start application";
81 qt_pipe_link_rep::write (string s
, int channel
) {
82 if ((!alive
) || (channel
!= LINK_IN
)) return;
83 if (-1 == PipeLink
.writeStdin (s
)) {
84 cerr
<< "TeXmacs] Error: cannot write to '" << PipeLink
.cmd
<< "'\n";
85 PipeLink
.killProcess ();
90 qt_pipe_link_rep::feed (int channel
) {
91 if ((!alive
) || ((channel
!= LINK_OUT
) && (channel
!= LINK_ERR
))) return;
92 if (channel
== LINK_OUT
) PipeLink
.feedBuf (QProcess::StandardOutput
);
93 else PipeLink
.feedBuf (QProcess::StandardError
);
97 qt_pipe_link_rep::watch (int channel
) {
98 static string empty_string
= "";
99 if (channel
== LINK_OUT
) return PipeLink
.getOutbuf ();
100 else if (channel
== LINK_ERR
) return PipeLink
.getErrbuf ();
101 else return empty_string
;
105 qt_pipe_link_rep::read (int channel
) {
106 if (channel
== LINK_OUT
) {
107 string r
= PipeLink
.getOutbuf ();
108 PipeLink
.setOutbuf ("");
111 else if (channel
== LINK_ERR
) {
112 string r
= PipeLink
.getErrbuf ();
113 PipeLink
.setErrbuf ("");
116 else return string("");
120 qt_pipe_link_rep::listen (int msecs
) {
122 time_t wait_until
= texmacs_time () + msecs
;
123 while ((PipeLink
.getOutbuf() == "") && (PipeLink
.getErrbuf() == "")) {
124 PipeLink
.listenChannel (QProcess::StandardOutput
, 0);
125 PipeLink
.listenChannel (QProcess::StandardError
, 0);
126 if (texmacs_time () - wait_until
> 0) break;
131 qt_pipe_link_rep::is_readable (int channel
) {
132 if ((!alive
) || ((channel
!= LINK_OUT
) && (channel
!= LINK_ERR
))) return false;
133 if (channel
== LINK_OUT
) PipeLink
.listenChannel (QProcess::StandardOutput
, 0);
134 else PipeLink
.listenChannel (QProcess::StandardError
, 0);
138 qt_pipe_link_rep::interrupt () {
140 #if defined(__MINGW__) || defined(__MINGW32__)
143 ::killpg(PipeLink
.pid (), SIGINT
);
148 qt_pipe_link_rep::stop () {
149 PipeLink
.killProcess ();
153 /******************************************************************************
154 * Main builder function for qt_pipe_links
155 ******************************************************************************/
158 make_pipe_link (string cmd
) {
159 return tm_new
<qt_pipe_link_rep
> (cmd
);
162 /******************************************************************************
163 * Emergency exit for all pipes
164 ******************************************************************************/
168 iterator
<pointer
> it
= iterate (pipe_link_set
);
170 qt_pipe_link_rep
* con
= (qt_pipe_link_rep
*) it
->next();
171 if (con
->alive
) con
->stop ();
176 process_all_pipes () {
177 iterator
<pointer
> it
= iterate (pipe_link_set
);
179 qt_pipe_link_rep
* con
= (qt_pipe_link_rep
*) it
->next();
180 if (con
->alive
) con
->apply_command ();
184 #endif // defined (QTTEXMACS) && (defined (__MINGW__) || defined (__MINGW32__))