qlockfile_unix.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/corelib/io/qlockfile_unix.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4-
5-
6-
7static QByteArray localHostName()-
8{-
9 QByteArray hostName(512, Qt::Uninitialized);-
10 if (gethostname(hostName.data(), hostName.size()) == -1)-
11 return QByteArray();-
12 hostName.truncate(strlen(hostName.data()));-
13 return hostName;-
14}-
15-
16-
17static qint64 qt_write_loop(int fd, const char *data, qint64 len)-
18{-
19 qint64 pos = 0;-
20 while (pos < len) {-
21 const qint64 ret = qt_safe_write(fd, data + pos, len - pos);-
22 if (ret == -1)-
23 return pos;-
24 pos += ret;-
25 }-
26 return pos;-
27}-
28-
29int QLockFilePrivate::checkFcntlWorksAfterFlock(const QString &fn)-
30{-
31-
32 QTemporaryFile file(fn);-
33 if (!file.open())-
34 return 0;-
35 const int fd = file.d_func()->engine()->handle();-
36-
37 if (flock(fd, 2 | 4) == -1)-
38 return 0;-
39-
40 struct flock flockData;-
41 flockData.l_type = 1;-
42 flockData.l_whence = 0;-
43 flockData.l_start = 0;-
44 flockData.l_len = 0;-
45 flockData.l_pid = getpid();-
46 if (fcntl(fd, 6, &flockData) == -1)-
47 return 0;-
48 return 1;-
49-
50-
51-
52}-
53-
54-
55-
56-
57-
58-
59-
60typedef QCache<QString, bool> CacheType;-
61namespace { namespace Q_QGS_fcntlOK { typedef CacheType Type; QBasicAtomicInt guard = { QtGlobalStatic::Uninitialized }; __attribute__((visibility("hidden"))) inline Type *innerFunction() { struct HolderBase { ~HolderBase() noexcept { if (guard.load() == QtGlobalStatic::Initialized) guard.store(QtGlobalStatic::Destroyed); } }; static struct Holder : public HolderBase { Type value; Holder() noexcept(noexcept(Type (10))) : value (10) { guard.store(QtGlobalStatic::Initialized); } } holder; return &holder.value; } } } static QGlobalStatic<CacheType, Q_QGS_fcntlOK::innerFunction, Q_QGS_fcntlOK::guard> fcntlOK;;-
62static QBasicMutex fcntlLock;-
63-
64-
65-
66-
67-
68-
69static bool fcntlWorksAfterFlock(const QString &fn)-
70{-
71 QMutexLocker lock(&fcntlLock);-
72 if (fcntlOK.isDestroyed())-
73 return QLockFilePrivate::checkFcntlWorksAfterFlock(fn);-
74 bool *worksPtr = fcntlOK->object(fn);-
75 if (worksPtr)-
76 return *worksPtr;-
77-
78 const bool val = QLockFilePrivate::checkFcntlWorksAfterFlock(fn);-
79 worksPtr = new bool(val);-
80 fcntlOK->insert(fn, worksPtr);-
81-
82 return val;-
83}-
84-
85static bool setNativeLocks(const QString &fileName, int fd)-
86{-
87-
88 if (flock(fd, 2 | 4) == -1)-
89 return false;-
90-
91 struct flock flockData;-
92 flockData.l_type = 1;-
93 flockData.l_whence = 0;-
94 flockData.l_start = 0;-
95 flockData.l_len = 0;-
96 flockData.l_pid = getpid();-
97 if (fcntlWorksAfterFlock(QDir::cleanPath(QFileInfo(fileName).absolutePath()) + QString('/'))-
98 && fcntl(fd, 6, &flockData) == -1) {-
99 return false;-
100 }-
101 return true;-
102}-
103-
104QLockFile::LockError QLockFilePrivate::tryLock_sys()-
105{-
106-
107-
108-
109 QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n'-
110 % QCoreApplication::applicationName().toUtf8() % '\n'-
111 % localHostName() % '\n';-
112-
113 const QByteArray lockFileName = QFile::encodeName(fileName);-
114 const int fd = qt_safe_open(lockFileName.constData(), 01 | 0100 | 0200, 0666);-
115 if (fd < 0) {-
116 switch ((*__errno_location ())) {-
117 case 17:-
118 return QLockFile::LockFailedError;-
119 case 13:-
120 case 30:-
121 return QLockFile::PermissionError;-
122 default:-
123 return QLockFile::UnknownError;-
124 }-
125 }-
126-
127 if (!setNativeLocks(fileName, fd)) {-
128 const int errnoSaved = (*__errno_location ());-
129 QMessageLogger(__FILE__, 194206, __PRETTY_FUNCTION__).warning() << "setNativeLocks failed:" << qt_error_string(errnoSaved);-
130 }-
131-
132 if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size()) {-
133 close(fd);-
134 if (!QFile::remove(fileName))-
135 QMessageLogger(__FILE__, 200212, __PRETTY_FUNCTION__).warning("QLockFile: Could not remove our own lock file %s.", QString(fileName).toLocal8Bit().constData());-
136 return QLockFile::UnknownError;-
137 }-
138-
139-
140 fileHandle = fd;-
141-
142-
143-
144 fdatasync(fileHandle);-
145-
146-
147-
148-
149 return QLockFile::NoError;-
150}-
151-
152bool QLockFilePrivate::removeStaleLock()-
153{-
154 const QByteArray lockFileName = QFile::encodeName(fileName);-
155 const int fd = qt_safe_open(lockFileName.constData(), 01, 0666);-
156 if (fd < 0)-
157 return false;-
158 bool success = setNativeLocks(fileName, fd) && (::unlink(lockFileName) == 0);-
159 close(fd);-
160 return success;-
161}-
162-
163bool QLockFilePrivate::isApparentlyStale() const-
164{-
165 qint64 pid;-
166 QString hostname, appname;-
167 if (getLockInfo(&pid, &hostname, &appname)) {-
168 if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {-
169 if (::kill(pid, 0) == -1 && (*__errno_location ()) == 3)-
170 return true;-
171 const QString processName = processNameByPid(pid);-
172 if (!processName.isEmpty()) {-
173 QFileInfo fi(appname);-
174 if (fi.isSymLink())-
175 fi.setFile(fi.symLinkTarget());-
176 if (processName != fi.fileName())-
177 return true;-
178 }-
179 }-
180 }-
181 const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());-
182 return staleLockTime > 0 && age > staleLockTime;-
183}-
184-
185QString QLockFilePrivate::processNameByPid(qint64 pid)-
186{-
187-
188-
189-
190-
191-
192 if (!QFile::exists(([]() -> QString { enum { Size = sizeof(u"" "/proc/version")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "/proc/version" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()))
!QFile::exists...al_temp; }()))Description
TRUEnever evaluated
FALSEevaluated 12 times by 1 test
Evaluated by:
  • tst_QLockFile
)
0-12
193 return
never executed: return QString();
QString();
never executed: return QString();
0
194 char exePath[64];-
195 char buf[4096 + 1];-
196 sprintf(exePath, "/proc/%lld/exe", pid);-
197 size_t len = (size_t)readlink(exePath, buf, sizeof(buf));-
198 if (len >= sizeof(buf)
len >= sizeof(buf)Description
TRUEnever evaluated
FALSEevaluated 12 times by 1 test
Evaluated by:
  • tst_QLockFile
) {
0-12
199-
200 return
never executed: return ([]() -> QString { enum { Size = sizeof(u"" "/ERROR/")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "/ERROR/" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }());
([]() -> QString { enum { Size = sizeof(u"" "/ERROR/")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "/ERROR/" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return
never executed: return qstring_literal_temp;
qstring_literal_temp;
never executed: return qstring_literal_temp;
}());
never executed: return ([]() -> QString { enum { Size = sizeof(u"" "/ERROR/")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "/ERROR/" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }());
0
201 }-
202 buf[len] = 0;-
203 return
executed 12 times by 1 test: return QFileInfo(QFile::decodeName(buf)).fileName();
Executed by:
  • tst_QLockFile
QFileInfo(QFile::decodeName(buf)).fileName();
executed 12 times by 1 test: return QFileInfo(QFile::decodeName(buf)).fileName();
Executed by:
  • tst_QLockFile
12
204}-
205-
206void QLockFile::unlock()-
207{-
208 QLockFilePrivate * const d = d_func();-
209 if (!d->isLocked)-
210 return;-
211 close(d->fileHandle);-
212 d->fileHandle = -1;-
213 if (!QFile::remove(d->fileName)) {-
214 QMessageLogger(__FILE__, 311328, __PRETTY_FUNCTION__).warning() << "Could not remove our own lock file" << d->fileName << "maybe permissions changed meanwhile?";-
215-
216 }-
217 d->lockError = QLockFile::NoError;-
218 d->isLocked = false;-
219}-
220-
221-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9