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