Vidalia  0.2.21
procutil.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 /*
12 ** \file procutil.cpp
13 ** \brief Process information and pidfile functions
14 */
15 
16 #include "procutil.h"
17 #include "stringutil.h"
18 
19 #include <QDir>
20 #include <QFile>
21 #include <QFileInfo>
22 #include <QTextStream>
23 #include <QApplication>
24 
25 
26 /** Returns the PID of the current process. */
27 qint64
29 {
30 #if defined(Q_OS_WIN)
31  return (qint64)GetCurrentProcessId();
32 #else
33  return (qint64)getpid();
34 #endif
35 }
36 
37 /** Returns true if a process with the given PID is running. */
38 bool
39 is_process_running(qint64 pid)
40 {
41 #if defined(Q_OS_WIN)
42  QHash<qint64, QString> procList = win32_process_list();
43  if (procList.contains(pid)) {
44  /* A process with this ID exists. Check if it's the same as this process. */
45  QString exeFile = procList.value(pid);
46  QString thisExe = QFileInfo(QApplication::applicationFilePath()).fileName();
47  return (exeFile.toLower() == thisExe.toLower());
48  }
49  return false;
50 #else
51  /* Send the "null" signal to check if a process exists */
52  if (kill((pid_t)pid, 0) < 0) {
53  return (errno != ESRCH);
54  }
55  return true;
56 #endif
57 }
58 
59 /** Writes the given file to disk containing the current process's PID. */
60 bool
61 write_pidfile(const QString &pidFileName, QString *errmsg)
62 {
63  /* Make sure the directory exists */
64  QDir pidFileDir = QFileInfo(pidFileName).absoluteDir();
65  if (!pidFileDir.exists()) {
66  pidFileDir.mkpath(QDir::convertSeparators(pidFileDir.absolutePath()));
67  }
68 
69  /* Try to open (and create if it doesn't exist) the pidfile */
70  QFile pidfile(pidFileName);
71  if (!pidfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
72  return err(errmsg, pidfile.errorString());
73  }
74 
75  /* Write our current PID to it */
76  QTextStream pidstream(&pidfile);
77  pidstream << get_pid();
78  return true;
79 }
80 
81 /** Reads the given pidfile and returns the value contained in it. If the file
82  * does not exist 0 is returned. Returns -1 if an error occurs. */
83 qint64
84 read_pidfile(const QString &pidFileName, QString *errmsg)
85 {
86  qint64 pid;
87 
88  /* Open the pidfile, if it exists */
89  QFile pidfile(pidFileName);
90  if (!pidfile.exists()) {
91  return 0;
92  }
93  if (!pidfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
94  if (errmsg) {
95  *errmsg = pidfile.errorString();
96  }
97  return -1;
98  }
99 
100  /* Read the PID in from the file */
101  QTextStream pidstream(&pidfile);
102  pidstream >> pid;
103  return pid;
104 }
105 
106 QHash<qint64, QString>
108 {
109 #if defined(Q_OS_WIN32)
110  return win32_process_list();
111 #else
112  return QHash<qint64, QString>();
113 #endif
114 }
115 
116 bool
117 process_kill(qint64 pid)
118 {
119 #if defined(Q_OS_WIN32)
120  HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE,
121  static_cast<DWORD>(pid));
122  if (hProcess == NULL)
123  return false;
124 
125  BOOL ret = TerminateProcess(hProcess, 0);
126  CloseHandle(hProcess);
127 
128  return (ret != FALSE);
129 #else
130  return false;
131 #endif
132 }
133