Vidalia 0.2.15
HelperProcess.cpp
Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If you
00004 **  did not receive the LICENSE file with this file, you may obtain it from the
00005 **  Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.torproject.org/projects/vidalia.html. No part of Vidalia, 
00007 **  including this file, may be copied, modified, propagated, or distributed 
00008 **  except according to the terms described in the LICENSE file.
00009 */
00010 /*
00011 **  This file was originally written by Steven J. Murdoch, and 
00012 **  modified by Matt Edman. It is distributed under the following
00013 **  license:
00014 **
00015 **  Copyright (C) 2007, Matt Edman
00016 **  Copyright (C) 2007, Steven J. Murdoch 
00017 **                      <http://www.cl.cam.ac.uk/users/sjm217/>
00018 **
00019 **  This program is free software; you can redistribute it and/or
00020 **  modify it under the terms of the GNU General Public License
00021 **  as published by the Free Software Foundation; either version 2
00022 **  of the License, or (at your option) any later version.
00023 **
00024 **  This program is distributed in the hope that it will be useful,
00025 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 **  GNU General Public License for more details.
00028 **
00029 **  You should have received a copy of the GNU General Public License
00030 **  along with this program; if not, write to the Free Software
00031 **  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00032 **  Boston, MA  02110-1301, USA.
00033 */
00034 
00035 /*
00036 ** \file helperprocess.cpp
00037 ** \brief Invokes a web browser process (originally by Steven. J. Murdoch)
00038 */
00039 
00040 #include "HelperProcess.h"
00041 #include "Vidalia.h"
00042 
00043 #include "stringutil.h"
00044 
00045 #include <QString>
00046 #include <QFileInfo>
00047 
00048 #ifdef Q_WS_MAC 
00049 #include <Carbon/Carbon.h> 
00050 #endif 
00051 
00052 /** Default constructor */
00053 HelperProcess::HelperProcess(QObject *parent)
00054 : QProcess(parent)
00055 {
00056   // Call error handling routine on errors
00057   QObject::connect(this, SIGNAL(error(QProcess::ProcessError)),
00058                    this, SLOT(onError(QProcess::ProcessError)));
00059 
00060   // Call output handling routines on process output
00061   QObject::connect(this, SIGNAL(readyReadStandardError()),
00062                    this, SLOT(onReadyReadStandardError()));
00063   QObject::connect(this, SIGNAL(readyReadStandardOutput()),
00064                    this, SLOT(onReadyReadStandardOutput()));
00065 }
00066 
00067 /** Invoked when output is written to the process's stderr. */
00068 void
00069 HelperProcess::onReadyReadStandardError()
00070 {
00071   QString output = QString(readAllStandardError());
00072   foreach (QString line, output.split("\n")) {
00073     vInfo("(%1:stderr): %2").arg(_processName).arg(line);
00074   }
00075 }
00076 
00077 /** Invoked when output is written to the process's stdout. */
00078 void
00079 HelperProcess::onReadyReadStandardOutput()
00080 {
00081   QString output = QString(readAllStandardOutput());
00082   foreach (QString line, output.split("\n")) {
00083     vInfo("(%1:stdout): %2").arg(_processName).arg(line);
00084   }
00085 }
00086 
00087 void
00088 HelperProcess::start(const QString &app, const QString &args)
00089 {
00090   QFileInfo fi(app);
00091   _processName = fi.fileName();
00092 
00093   QString commandLine = QString("\"%1\" %2").arg(app).arg(args);
00094 
00095    // Log the process name and arguments
00096   vNotice("Launching helper process with command line '%1'")
00097                                            .arg(commandLine);
00098 
00099   QProcess::start(commandLine, QIODevice::ReadOnly | QIODevice::Text);
00100 }
00101 
00102 /** Start the specified application. */
00103 void
00104 HelperProcess::start(const QString &app, const QStringList &args) 
00105 {
00106   // Remember the executable name of the process
00107   QFileInfo fi(app);
00108   _processName = fi.fileName();
00109 
00110   // Log the process name and arguments
00111   vNotice("Launching helper process '%1' with arguments '%2'").arg(app)
00112                                      .arg(string_format_arguments(args));
00113 
00114   // Start the specified application
00115   QProcess::start(app, args, QIODevice::ReadOnly | QIODevice::Text);
00116 }
00117 
00118 /** Invoked when underlying QProcess fails. */
00119 void
00120 HelperProcess::onError(QProcess::ProcessError error)
00121 {
00122   // Pass up error messages on startup, but ignore the rest
00123   if (error == QProcess::FailedToStart) {
00124     vWarn("Helper process '%1' failed to start: %2").arg(_processName)
00125                                                     .arg(errorString());
00126     emit startFailed(errorString());
00127   }
00128 }
00129 
00130 /** Returns true iff process is not running. */
00131 bool
00132 HelperProcess::isDone() const
00133 {
00134   return state() == NotRunning;
00135 }
00136 
00137 void
00138 HelperProcess::toForeground()
00139 {
00140 #if defined(Q_WS_MAC) 
00141   ProcessSerialNumber psn;
00142   OSStatus st;
00143 
00144   do {
00145     st = GetProcessForPID(pid(), &psn);
00146   } while(st == -600);
00147 
00148   SetFrontProcess(&psn);
00149 #endif 
00150 }