Vidalia 0.2.12
|
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 ** \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