25 #include <sys/types.h>
26 #ifdef HAVE_SYS_STAT_H
29 #ifdef HAVE_SYS_TIME_H
37 #include <QtCore/QDate>
38 #include <QtCore/QFile>
39 #include <QTextStream>
74 class KLockFile::Private
80 linkCountSupport(true),
97 void writeIntoLockFile(QFile& file,
const KComponentData& componentData);
105 bool linkCountSupport;
108 KDE_struct_stat statBuf;
117 : d(new Private(componentData))
119 d->m_fileName = file;
138 d->staleTime = _staleTime;
142 const KDE_struct_stat &st_buf2)
144 #define FIELD_EQ(what) (st_buf1.what == st_buf2.what)
151 const KDE_struct_stat& st_buf2 )
153 return !(st_buf1 == st_buf2);
158 KDE_struct_stat st_buf;
161 if(!::link( fileName, QByteArray(fileName+
".test") )) {
162 result = KDE_lstat( fileName, &st_buf );
163 ::unlink( QByteArray(fileName+
".test") );
165 return (result < 0 || ((result == 0) && (st_buf.st_nlink == 2)));
168 void KLockFile::Private::writeIntoLockFile(QFile& file,
const KComponentData& componentData)
170 file.setPermissions(QFile::ReadUser|QFile::WriteUser|QFile::ReadGroup|QFile::ReadOther);
174 gethostname(hostname, 255);
176 m_hostname = QString::fromLocal8Bit(hostname);
179 QTextStream stream(&file);
182 stream << QString::number(m_pid) << endl
183 << m_componentName << endl
184 << m_hostname << endl;
188 void KLockFile::Private::readLockFile()
192 m_componentName.clear();
194 QFile file(m_fileName);
195 if (file.open(QIODevice::ReadOnly))
197 QTextStream ts(&file);
199 m_pid = ts.readLine().toInt();
201 m_componentName = ts.readLine();
203 m_hostname = ts.readLine();
209 const QByteArray lockFileName = QFile::encodeName( m_fileName );
210 int result = KDE_lstat( lockFileName, &st_buf );
216 uniqueFile.setFileTemplate(m_fileName);
217 if (!uniqueFile.open())
220 writeIntoLockFile(uniqueFile, m_componentData);
222 QByteArray uniqueName = QFile::encodeName( uniqueFile.fileName() );
225 result = ::link( uniqueName, lockFileName );
229 if (!linkCountSupport)
232 KDE_struct_stat st_buf2;
233 result = KDE_lstat( uniqueName, &st_buf2 );
237 result = KDE_lstat( lockFileName, &st_buf );
241 if (st_buf != st_buf2 || S_ISLNK(st_buf.st_mode) || S_ISLNK(st_buf2.st_mode))
245 if ((st_buf2.st_nlink > 1 ||
246 ((st_buf.st_nlink == 1) && (st_buf2.st_nlink == 1))) && (st_buf.st_ino != st_buf2.st_ino))
249 if (!linkCountSupport)
258 bool KLockFile::Private::isNfs()
const
267 return lockFileWithLink(st_buf);
270 return lockFileOExcl(st_buf);
275 const QByteArray lockFileName = QFile::encodeName( m_fileName );
277 int fd = KDE_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644);
279 if (errno == EEXIST) {
287 if (!m_file.open(fd, QIODevice::WriteOnly)) {
291 writeIntoLockFile(m_file, m_componentData);
294 const int result = KDE_lstat(QFile::encodeName(m_fileName), &st_buf);
303 return deleteStaleLockWithLink();
308 qWarning(
"WARNING: deleting stale lockfile %s", qPrintable(m_fileName));
309 QFile::remove(m_fileName);
320 ktmpFile->setFileTemplate(m_fileName);
321 if (!ktmpFile->open()) {
326 const QByteArray lckFile = QFile::encodeName(m_fileName);
327 const QByteArray tmpFile = QFile::encodeName(ktmpFile->fileName());
331 if (::link(lckFile, tmpFile) != 0)
336 KDE_struct_stat st_buf1;
337 KDE_struct_stat st_buf2;
338 memcpy(&st_buf1, &statBuf,
sizeof(KDE_struct_stat));
340 if ((KDE_lstat(tmpFile, &st_buf2) == 0) && st_buf1 == st_buf2)
342 if ((KDE_lstat(lckFile, &st_buf2) == 0) && st_buf1 == st_buf2)
345 qWarning(
"WARNING: deleting stale lockfile %s", lckFile.data());
353 if (linkCountSupport)
358 if (!linkCountSupport)
361 qWarning(
"WARNING: deleting stale lockfile %s", lckFile.data());
363 if (::unlink(lckFile) < 0) {
364 qWarning(
"WARNING: Problem deleting stale lockfile %s: %s", lckFile.data(),
372 qWarning(
"WARNING: Problem deleting stale lockfile %s", lckFile.data());
388 KDE_struct_stat st_buf;
390 result = d->lockFile(st_buf);
394 d->staleTimer = QTime();
399 d->staleTimer = QTime();
400 if (--hardErrors == 0)
407 if (!d->staleTimer.isNull() && d->statBuf != st_buf)
408 d->staleTimer = QTime();
410 if (d->staleTimer.isNull())
412 memcpy(&(d->statBuf), &st_buf,
sizeof(KDE_struct_stat));
413 d->staleTimer.start();
418 bool isStale =
false;
419 if ((d->m_pid > 0) && !d->m_hostname.isEmpty())
424 gethostname(hostname, 255);
427 if (d->m_hostname == QLatin1String(hostname))
430 int res = ::kill(d->m_pid, 0);
431 if ((res == -1) && (errno == ESRCH))
435 if (d->staleTimer.elapsed() > (d->staleTime*1000))
443 result = d->deleteStaleLock();
448 d->staleTimer = QTime();
467 select(0, 0, 0, 0, &tv);
483 ::unlink(QFile::encodeName(d->m_fileName));
484 if (d->mustCloseFd) {
485 close(d->m_file.handle());
486 d->mustCloseFd =
false;
499 hostname = d->m_hostname;
500 appname = d->m_componentName;