comparison base/TempDirectory.cpp @ 98:604bd4ee3ed4

* Add a method in System.{cpp,h} to try to establish whether a process of a given pid is running or not * Make TempDirectory store its process ID, and clean up any old temporary directories it finds that correspond to non-running processes
author Chris Cannam
date Fri, 05 May 2006 11:28:04 +0000
parents e076e676439b
children 68ff162fdbc3
comparison
equal deleted inserted replaced
97:22494cc28c9f 98:604bd4ee3ed4
12 License, or (at your option) any later version. See the file 12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information. 13 COPYING included with this distribution for more information.
14 */ 14 */
15 15
16 #include "TempDirectory.h" 16 #include "TempDirectory.h"
17 #include "System.h"
17 18
18 #include <QDir> 19 #include <QDir>
19 #include <QFile> 20 #include <QFile>
20 #include <QMutexLocker> 21 #include <QMutexLocker>
21 22
68 { 69 {
69 QMutexLocker locker(&m_mutex); 70 QMutexLocker locker(&m_mutex);
70 71
71 if (m_tmpdir != "") return m_tmpdir; 72 if (m_tmpdir != "") return m_tmpdir;
72 73
73 //!!! QDir tempDirBase = QDir::temp(); 74 QString svDirBase = ".sv";
74 QDir tempDirBase = QDir::home(); 75 QString svDir = QDir::home().filePath(svDirBase);
76 if (!QFileInfo(svDir).exists()) {
77 if (!QDir::home().mkdir(svDirBase)) {
78 throw DirectoryCreationFailed(QString("%1 directory in $HOME")
79 .arg(svDirBase));
80 }
81 } else if (!QFileInfo(svDir).isDir()) {
82 throw DirectoryCreationFailed(QString("$HOME/%1 is not a directory")
83 .arg(svDirBase));
84 }
85
86 cleanupAbandonedDirectories(svDir);
87
88 return createTempDirectoryIn(svDir);
89 }
90
91 QString
92 TempDirectory::createTempDirectoryIn(QString dir)
93 {
94 // Entered with mutex held.
95
96 QDir tempDirBase(dir);
75 97
76 // Generate a temporary directory. Qt4.1 doesn't seem to be able 98 // Generate a temporary directory. Qt4.1 doesn't seem to be able
77 // to do this for us, and mkdtemp is not standard. This method is 99 // to do this for us, and mkdtemp is not standard. This method is
78 // based on the way glibc does mkdtemp. 100 // based on the way glibc does mkdtemp.
79 101
108 } 130 }
109 131
110 if (m_tmpdir == "") { 132 if (m_tmpdir == "") {
111 throw DirectoryCreationFailed(QString("temporary subdirectory in %1") 133 throw DirectoryCreationFailed(QString("temporary subdirectory in %1")
112 .arg(tempDirBase.canonicalPath())); 134 .arg(tempDirBase.canonicalPath()));
135 }
136
137 QString pidpath = QDir(m_tmpdir).filePath(QString("%1.pid").arg(getpid()));
138 QFile pidfile(pidpath);
139
140 if (!pidfile.open(QIODevice::WriteOnly)) {
141 throw DirectoryCreationFailed(QString("pid file creation in %1")
142 .arg(m_tmpdir));
143 } else {
144 pidfile.close();
113 } 145 }
114 146
115 return m_tmpdir; 147 return m_tmpdir;
116 } 148 }
117 149
194 if (isRoot) { 226 if (isRoot) {
195 m_tmpdir = ""; 227 m_tmpdir = "";
196 m_mutex.unlock(); 228 m_mutex.unlock();
197 } 229 }
198 } 230 }
231
232 void
233 TempDirectory::cleanupAbandonedDirectories(QString svDir)
234 {
235 QDir dir(svDir, "sv_*", QDir::Name, QDir::Dirs);
236
237 for (unsigned int i = 0; i < dir.count(); ++i) {
238
239 QDir subdir(dir.filePath(dir[i]), "*.pid", QDir::Name, QDir::Files);
240
241 for (unsigned int j = 0; j < subdir.count(); ++j) {
242
243 bool ok = false;
244 int pid = QFileInfo(subdir[j]).baseName().toInt(&ok);
245 if (!ok) continue;
246
247 if (GetProcessStatus(pid) == ProcessNotRunning) {
248 std::cerr << "INFO: Found abandoned temporary directory from "
249 << "an old Sonic Visualiser process\n(pid=" << pid
250 << ", directory=\""
251 << dir.filePath(dir[i]).toStdString()
252 << "\"). Removing it..." << std::endl;
253 cleanupDirectory(dir.filePath(dir[i]));
254 std::cerr << "...done." << std::endl;
255 break;
256 }
257 }
258 }
259 }
260
261
262