Vidalia  0.3.1
HelperProcess.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If you
4 ** did not receive the LICENSE file with this file, you may obtain it from the
5 ** Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 /*
11 ** This file was originally written by Steven J. Murdoch, and
12 ** modified by Matt Edman. It is distributed under the following
13 ** license:
14 **
15 ** Copyright (C) 2007, Matt Edman
16 ** Copyright (C) 2007, Steven J. Murdoch
17 ** <http://www.cl.cam.ac.uk/users/sjm217/>
18 **
19 ** This program is free software; you can redistribute it and/or
20 ** modify it under the terms of the GNU General Public License
21 ** as published by the Free Software Foundation; either version 2
22 ** of the License, or (at your option) any later version.
23 **
24 ** This program is distributed in the hope that it will be useful,
25 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
26 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 ** GNU General Public License for more details.
28 **
29 ** You should have received a copy of the GNU General Public License
30 ** along with this program; if not, write to the Free Software
31 ** Foundation, Inc., 51 Franklin Street, Fifth Floor,
32 ** Boston, MA 02110-1301, USA.
33 */
34 
35 /*
36 ** \file helperprocess.cpp
37 ** \brief Invokes a web browser process (originally by Steven. J. Murdoch)
38 */
39 
40 #include "HelperProcess.h"
41 #include "Vidalia.h"
42 
43 #include "stringutil.h"
44 
45 #include <QString>
46 #include <QFileInfo>
47 
48 #ifdef Q_WS_MAC
49 #include <Carbon/Carbon.h>
50 #endif
51 
52 /** Default constructor */
54 : QProcess(parent)
55 {
56  // Call error handling routine on errors
57  QObject::connect(this, SIGNAL(error(QProcess::ProcessError)),
58  this, SLOT(onError(QProcess::ProcessError)));
59 
60  // Call output handling routines on process output
61  QObject::connect(this, SIGNAL(readyReadStandardError()),
62  this, SLOT(onReadyReadStandardError()));
63  QObject::connect(this, SIGNAL(readyReadStandardOutput()),
64  this, SLOT(onReadyReadStandardOutput()));
65 }
66 
67 /** Invoked when output is written to the process's stderr. */
68 void
70 {
71  QString output = QString(readAllStandardError());
72  foreach (QString line, output.split("\n")) {
73  vInfo("(%1:stderr): %2").arg(_processName).arg(line);
74  }
75 }
76 
77 /** Invoked when output is written to the process's stdout. */
78 void
80 {
81  QString output = QString(readAllStandardOutput());
82  foreach (QString line, output.split("\n")) {
83  vInfo("(%1:stdout): %2").arg(_processName).arg(line);
84  }
85 }
86 
87 void
88 HelperProcess::start(const QString &app, const QString &args)
89 {
90  QFileInfo fi(app);
91  _processName = fi.fileName();
92 
93  QString commandLine = QString("\"%1\" %2").arg(app).arg(args);
94 
95  // Log the process name and arguments
96  vNotice("Launching helper process with command line '%1'")
97  .arg(commandLine);
98 
99  QProcess::start(commandLine, QIODevice::ReadOnly | QIODevice::Text);
100 }
101 
102 /** Start the specified application. */
103 void
104 HelperProcess::start(const QString &app, const QStringList &args)
105 {
106  // Remember the executable name of the process
107  QFileInfo fi(app);
108  _processName = fi.fileName();
109 
110  // Log the process name and arguments
111  vNotice("Launching helper process '%1' with arguments '%2'").arg(app)
112  .arg(string_format_arguments(args));
113 
114  // Start the specified application
115  QProcess::start(app, args, QIODevice::ReadOnly | QIODevice::Text);
116 }
117 
118 /** Invoked when underlying QProcess fails. */
119 void
120 HelperProcess::onError(QProcess::ProcessError error)
121 {
122  // Pass up error messages on startup, but ignore the rest
123  if (error == QProcess::FailedToStart) {
124  vWarn("Helper process '%1' failed to start: %2").arg(_processName)
125  .arg(errorString());
126  emit startFailed(errorString());
127  }
128 }
129 
130 /** Returns true iff process is not running. */
131 bool
133 {
134  return state() == NotRunning;
135 }
136 
137 void
139 {
140 #if defined(Q_WS_MAC)
141  ProcessSerialNumber psn;
142  OSStatus st;
143 
144  do {
145  st = GetProcessForPID(pid(), &psn);
146  } while(st == -600);
147 
148  SetFrontProcess(&psn);
149 #endif
150 }
DebugMessage error(const QString &fmt)
Definition: tcglobal.cpp:40
QString string_format_arguments(const QStringList &args)
Definition: stringutil.cpp:360
HelperProcess(QObject *parent=0)
#define vInfo(fmt)
Definition: Vidalia.h:40
void start(const QString &app, const QString &args)
void onReadyReadStandardError()
void onReadyReadStandardOutput()
void startFailed(const QString &errorMessage)
#define vNotice(fmt)
Definition: Vidalia.h:41
stop errmsg connect(const QHostAddress &address, quint16 port)
void onError(QProcess::ProcessError error)
#define vWarn(fmt)
Definition: Vidalia.h:42
bool isDone() const
QString _processName
Definition: HelperProcess.h:77