Vidalia  0.2.17
procutil.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 /*
00012 ** \file procutil.cpp
00013 ** \brief Process information and pidfile functions 
00014 */
00015 
00016 #include "procutil.h"
00017 #include "stringutil.h"
00018 
00019 #include <QDir>
00020 #include <QFile>
00021 #include <QFileInfo>
00022 #include <QTextStream>
00023 #include <QApplication>
00024 
00025 
00026 /** Returns the PID of the current process. */
00027 qint64
00028 get_pid()
00029 {
00030 #if defined(Q_OS_WIN)
00031   return (qint64)GetCurrentProcessId();
00032 #else
00033   return (qint64)getpid();
00034 #endif
00035 }
00036 
00037 /** Returns true if a process with the given PID is running. */
00038 bool
00039 is_process_running(qint64 pid)
00040 {
00041 #if defined(Q_OS_WIN)
00042   QHash<qint64, QString> procList = win32_process_list();
00043   if (procList.contains(pid)) {
00044     /* A process with this ID exists. Check if it's the same as this process. */
00045     QString exeFile = procList.value(pid);
00046     QString thisExe = QFileInfo(QApplication::applicationFilePath()).fileName();
00047     return (exeFile.toLower() == thisExe.toLower());
00048   }
00049   return false;
00050 #else
00051   /* Send the "null" signal to check if a process exists */
00052   if (kill((pid_t)pid, 0) < 0) {
00053     return (errno != ESRCH);
00054   }
00055   return true;
00056 #endif
00057 }
00058 
00059 /** Writes the given file to disk containing the current process's PID. */
00060 bool
00061 write_pidfile(const QString &pidFileName, QString *errmsg)
00062 {
00063   /* Make sure the directory exists */
00064   QDir pidFileDir = QFileInfo(pidFileName).absoluteDir();
00065   if (!pidFileDir.exists()) {
00066     pidFileDir.mkpath(QDir::convertSeparators(pidFileDir.absolutePath()));
00067   }
00068 
00069   /* Try to open (and create if it doesn't exist) the pidfile */
00070   QFile pidfile(pidFileName);
00071   if (!pidfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
00072     return err(errmsg, pidfile.errorString());
00073   }
00074 
00075   /* Write our current PID to it */
00076   QTextStream pidstream(&pidfile);
00077   pidstream << get_pid();
00078   return true;
00079 }
00080 
00081 /** Reads the given pidfile and returns the value contained in it. If the file
00082  * does not exist 0 is returned. Returns -1 if an error occurs. */
00083 qint64 
00084 read_pidfile(const QString &pidFileName, QString *errmsg)
00085 {
00086   qint64 pid;
00087   
00088   /* Open the pidfile, if it exists */
00089   QFile pidfile(pidFileName);
00090   if (!pidfile.exists()) {
00091     return 0;
00092   }
00093   if (!pidfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
00094     if (errmsg) {
00095       *errmsg = pidfile.errorString();
00096     }
00097     return -1; 
00098   }
00099   
00100   /* Read the PID in from the file */
00101   QTextStream pidstream(&pidfile);
00102   pidstream >> pid;
00103   return pid;
00104 }
00105 
00106 QHash<qint64, QString>
00107 process_list()
00108 {
00109 #if defined(Q_OS_WIN32)
00110   return win32_process_list();
00111 #else
00112   return QHash<qint64, QString>();
00113 #endif
00114 }
00115 
00116 bool
00117 process_kill(qint64 pid)
00118 {
00119 #if defined(Q_OS_WIN32)
00120   HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE,
00121                                 static_cast<DWORD>(pid));
00122   if (hProcess == NULL)
00123     return false;
00124 
00125   BOOL ret = TerminateProcess(hProcess, 0);
00126   CloseHandle(hProcess);
00127 
00128   return (ret != FALSE);
00129 #else
00130   return false;
00131 #endif
00132 }
00133