[KLF Application][KLF Tools][KLF Backend][KLF Home]
KLatexFormula Project
klfblockprocess.cpp
1 /***************************************************************************
2  * file klfblockprocess.cpp
3  * This file is part of the KLatexFormula Project.
4  * Copyright (C) 2011 by Philippe Faist
5  * philippe.faist@bluewin.ch
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program; if not, write to the *
19  * Free Software Foundation, Inc., *
20  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  ***************************************************************************/
22 /* $Id: klfblockprocess.cpp 862 2013-11-23 11:10:54Z phfaist $ */
23 
24 #include <ctype.h>
25 
26 #include <qprocess.h>
27 #include <qapplication.h>
28 #include <qeventloop.h>
29 #include <qfileinfo.h>
30 
31 #include "klfblockprocess.h"
32 
34 {
35 #ifdef KLFBACKEND_QT4
36  mProcessAppEvents = true;
37  connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(ourProcExited()));
38 #else
39  connect(this, SIGNAL(wroteToStdin()), this, SLOT(ourProcGotOurStdinData()));
40  connect(this, SIGNAL(processExited()), this, SLOT(ourProcExited()));
41 #endif
42 }
43 
44 
46 {
47 }
48 
49 void KLFBlockProcess::ourProcGotOurStdinData()
50 {
51 #ifndef KLFBACKEND_QT4
52  closeStdin();
53 #endif
54 }
55 
56 void KLFBlockProcess::ourProcExited()
57 {
58  _runstatus = 1; // exited
59 }
60 #ifndef KLFBACKEND_QT4
61 bool KLFBlockProcess::startProcess(QStringList cmd, QCString str, QStringList env)
62 {
63  return startProcess(cmd, QByteArray().duplicate(str.data(), str.length()), env);
64 }
65 #endif
67 {
68  return startProcess(cmd, QByteArray(), env);
69 }
70 
72 {
73  // klfDbg("Running: "<<cmd<<", stdindata/size="<<stdindata.size());
74 
75  _runstatus = 0;
76 
77  KLF_ASSERT_CONDITION(cmd.size(), "Empty command list given.", return false;) ;
78 
79 #if defined(Q_OS_UNIX) && defined(KLFBACKEND_QT4)
80 
81  // ** epstopdf bug in ubuntu: peek into executable, see if it is script. if it is, run with 'sh' on *nix's.
82  // this is a weird bug with QProcess that will not execute some script files like epstopdf.
83 
84  {
85  QString fn = cmd[0];
86  if (!QFile::exists(fn))
87  fn = klfSearchPath(cmd[0]);
88  QFile fpeek(fn);
89  if (!fpeek.open(QIODevice::ReadOnly)) {
90  //klfDbg("cmd[0]="<<cmd[0]<<", Can't peek into file "<<fn<<"!") ;
91  } else {
92  QByteArray line;
93  int n = 0, j;
94  bool isbinary = false;
95  while (n++ < 3 && (line = fpeek.readLine()).size()) {
96  for (j = 0; j < line.size(); ++j) {
97  if ( ! isascii(line[j]) ) {
98  isbinary = true;
99  break;
100  }
101  }
102  if (isbinary)
103  break;
104  }
105  if (!isbinary) {
106  // explicitely run with /usr/bin/env (we're on *nix, so OK)
107  cmd.prepend("/usr/bin/env");
108  }
109  }
110  }
111 
112 
113 #endif
114 
115  QString program = cmd[0];
116 
117  //klfDbg("Running cmd="<<cmd);
118  //klfDbg("env="<<env<<", curenv="<<environment());
119 
120 #ifdef KLFBACKEND_QT4
121  if (env.size() > 0) {
122  setEnvironment(env);
123  }
124 
125  QStringList args = cmd;
126  args.erase(args.begin());
127  //klfDbg("Starting "<<program<<", "<<args) ;
128  start(program, args);
129  if ( ! waitForStarted() ) {
130  //klfDbg("Can't wait for started! Error="<<error()) ;
131  return false;
132  }
133 
134  write(stdindata.constData(), stdindata.size());
136 
137  //klfDbg("wrote input data (size="<<stdindata.size()<<")") ;
138 
139 #else
140  setArguments(cmd);
141  QStringList *e = &env;
142  if (e->size() == 0)
143  e = 0;
144 
145  if (! start(e) )
146  return false;
147 
148  writeToStdin(stdindata);
149  // slot ourProcGotOutStdinData() should be called, which closes input
150 #endif
151 
152 #ifdef KLFBACKEND_QT4
153  if (mProcessAppEvents) {
154  while (_runstatus == 0) {
155  qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
156  }
157  } else {
158  if (!waitForFinished()) {
159  klfDbg("Can't wait for finished!");
160  return false;
161  }
162  }
163  klfDbg("Process should have finished now.");
164 #else
165  while (_runstatus == 0) {
166  qApp->processEvents(QEventLoop::ExcludeUserInput);
167  }
168 #endif
169 
170  if (_runstatus < 0) { // some error occurred somewhere
171  klfDbg("some error occurred, _runstatus="+QString("%1").arg(_runstatus)) ;
172  return false;
173  }
174 
175  return true;
176 }
177 
178 
179 
181 {
182  QStringList curenvironment;
183 #ifdef KLFBACKEND_QT4
184  curenvironment = QProcess::systemEnvironment();
185 #else
186  extern char ** environ;
187  int k;
188  for (k = 0; environ[k] != NULL; ++k) {
189  curenvironment.append(QString::fromLocal8Bit(environ[k]));
190  }
191 #endif
192  return curenvironment;
193 }
Defines the KLFBlockProcess class.
systemEnvironment()
#define klfDbg(streamableItems)
print debug stream items
bool startProcess(QStringList cmd, QByteArray stdindata, QStringList env=QStringList())
KLFBlockProcess(QObject *parent=0)
fromLocal8Bit(const char *str, int size=-1)
finished(int exitCode, QProcess::ExitStatus exitStatus)
KLF_EXPORT QString klfSearchPath(const QString &prog, const QString &extra_path="")
Smart executable searching in a given path list with wildcards.
Definition: klfdefs.cpp:1228
KLF_EXPORT QStringList klf_cur_environ()
The current process environment.
setEnvironment(const QStringList &environment)
open(OpenMode mode)
waitForStarted(int msecs=30000)
#define KLF_ASSERT_CONDITION(expr, msg, failaction)
Asserting Conditions (NON-FATAL)
closeWriteChannel()
ExitStatusQProcess::exitStatus()
start(const QString &program, const QStringList &arguments, OpenMode mode=ReadWrite)
waitForFinished(int msecs=30000)

Generated by doxygen 1.8.6