1 |
commit: e65b89b6e937ac0a2b3a37e07b08407511b6a692 |
2 |
Author: Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Oct 10 17:39:33 2020 +0000 |
4 |
Commit: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Sep 30 10:55:51 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/qt.git/commit/?id=e65b89b6 |
7 |
|
8 |
dev-qt/qtcore: Revert timezone handling to 5.14 state |
9 |
|
10 |
This is an obvious workaround, until we and upstream have |
11 |
decided what to do... |
12 |
|
13 |
(sync with Gentoo ebuild repository) |
14 |
|
15 |
Package-Manager: Portage-3.0.4, Repoman-3.0.1 |
16 |
Signed-off-by: Andreas K. Hüttel <dilfridge <AT> gentoo.org> |
17 |
Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org> |
18 |
|
19 |
dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch | 271 +++++++++++++++++++++ |
20 |
dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch | 47 ++++ |
21 |
dev-qt/qtcore/qtcore-5.15.2.9999.ebuild | 5 +- |
22 |
3 files changed, 322 insertions(+), 1 deletion(-) |
23 |
|
24 |
diff --git a/dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch |
25 |
new file mode 100644 |
26 |
index 00000000..1c8f1e89 |
27 |
--- /dev/null |
28 |
+++ b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-1.patch |
29 |
@@ -0,0 +1,271 @@ |
30 |
+From c337f6fae51b987ce7dbed1fd9bea41e6073efbb Mon Sep 17 00:00:00 2001 |
31 |
+From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o> |
32 |
+Date: Sat, 10 Oct 2020 19:26:13 +0200 |
33 |
+Subject: [PATCH 1/2] Revert "Cache system zone ID when fetched from the |
34 |
+ file-system" |
35 |
+ |
36 |
+This reverts commit c70ce3d042025c858faffe661f85d2482a2a0d8c. |
37 |
+--- |
38 |
+ src/corelib/time/qtimezoneprivate_tz.cpp | 205 +++++++---------------- |
39 |
+ 1 file changed, 64 insertions(+), 141 deletions(-) |
40 |
+ |
41 |
+diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp |
42 |
+index c5c70b7364..01f9a6cce0 100644 |
43 |
+--- a/src/corelib/time/qtimezoneprivate_tz.cpp |
44 |
++++ b/src/corelib/time/qtimezoneprivate_tz.cpp |
45 |
+@@ -1,6 +1,5 @@ |
46 |
+ /**************************************************************************** |
47 |
+ ** |
48 |
+-** Copyright (C) 2020 The Qt Company Ltd. |
49 |
+ ** Copyright (C) 2019 Crimson AS <info@×××××××.no> |
50 |
+ ** Copyright (C) 2013 John Layt <jlayt@×××.org> |
51 |
+ ** Contact: https://www.qt.io/licensing/ |
52 |
+@@ -43,19 +42,18 @@ |
53 |
+ #include "qtimezoneprivate_p.h" |
54 |
+ #include "private/qlocale_tools_p.h" |
55 |
+ |
56 |
+-#include <QtCore/QDataStream> |
57 |
+-#include <QtCore/QDateTime> |
58 |
+ #include <QtCore/QFile> |
59 |
+-#include <QtCore/QHash> |
60 |
+ #include <QtCore/QMutex> |
61 |
++#include <QtCore/QHash> |
62 |
++#include <QtCore/QDataStream> |
63 |
++#include <QtCore/QDateTime> |
64 |
+ |
65 |
+ #include <qdebug.h> |
66 |
+-#include <qplatformdefs.h> |
67 |
+ |
68 |
+ #include <algorithm> |
69 |
+ #include <errno.h> |
70 |
+ #include <limits.h> |
71 |
+-#ifndef Q_OS_INTEGRITY |
72 |
++#if !defined(Q_OS_INTEGRITY) |
73 |
+ #include <sys/param.h> // to use MAXSYMLINKS constant |
74 |
+ #endif |
75 |
+ #include <unistd.h> // to use _SC_SYMLOOP_MAX constant |
76 |
+@@ -1102,146 +1100,28 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs |
77 |
+ return last > tranCache().cbegin() ? dataForTzTransition(*--last) : invalidData(); |
78 |
+ } |
79 |
+ |
80 |
+-bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const |
81 |
+-{ |
82 |
+- return tzZones->contains(ianaId); |
83 |
+-} |
84 |
+- |
85 |
+-QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const |
86 |
+-{ |
87 |
+- QList<QByteArray> result = tzZones->keys(); |
88 |
+- std::sort(result.begin(), result.end()); |
89 |
+- return result; |
90 |
+-} |
91 |
+- |
92 |
+-QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const |
93 |
++static long getSymloopMax() |
94 |
+ { |
95 |
+- // TODO AnyCountry |
96 |
+- QList<QByteArray> result; |
97 |
+- for (auto it = tzZones->cbegin(), end = tzZones->cend(); it != end; ++it) { |
98 |
+- if (it.value().country == country) |
99 |
+- result << it.key(); |
100 |
+- } |
101 |
+- std::sort(result.begin(), result.end()); |
102 |
+- return result; |
103 |
+-} |
104 |
+- |
105 |
+-// Getting the system zone's ID: |
106 |
+- |
107 |
+-namespace { |
108 |
+-class ZoneNameReader : public QObject |
109 |
+-{ |
110 |
+-public: |
111 |
+- QByteArray name() |
112 |
+- { |
113 |
+- /* Assumptions: |
114 |
+- a) Systems don't change which of localtime and TZ they use without a |
115 |
+- reboot. |
116 |
+- b) When they change, they use atomic renames, hence a new device and |
117 |
+- inode for the new file. |
118 |
+- c) If we change which *name* is used for a zone, while referencing |
119 |
+- the same final zoneinfo file, we don't care about the change of |
120 |
+- name (e.g. if Europe/Oslo and Europe/Berlin are both symlinks to |
121 |
+- the same CET file, continuing to use the old name, after |
122 |
+- /etc/localtime changes which of the two it points to, is |
123 |
+- harmless). |
124 |
+- |
125 |
+- The alternative would be to use a file-system watcher, but they are a |
126 |
+- scarce resource. |
127 |
+- */ |
128 |
+- const StatIdent local = identify("/etc/localtime"); |
129 |
+- const StatIdent tz = identify("/etc/TZ"); |
130 |
+- if (!m_name.isEmpty() && m_last.isValid() && (m_last == local || m_last == tz)) |
131 |
+- return m_name; |
132 |
+- |
133 |
+- m_name = etcLocalTime(); |
134 |
+- if (!m_name.isEmpty()) { |
135 |
+- m_last = local; |
136 |
+- return m_name; |
137 |
+- } |
138 |
+- |
139 |
+- m_name = etcTZ(); |
140 |
+- m_last = m_name.isEmpty() ? StatIdent() : tz; |
141 |
+- return m_name; |
142 |
+- } |
143 |
+- |
144 |
+- |
145 |
+-private: |
146 |
+- QByteArray m_name; |
147 |
+- struct StatIdent |
148 |
+- { |
149 |
+- static constexpr unsigned long bad = ~0ul; |
150 |
+- unsigned long m_dev, m_ino; |
151 |
+- StatIdent() : m_dev(bad), m_ino(bad) {} |
152 |
+- StatIdent(const QT_STATBUF &data) : m_dev(data.st_dev), m_ino(data.st_ino) {} |
153 |
+- bool isValid() { return m_dev != bad || m_ino != bad; } |
154 |
+- bool operator==(const StatIdent &other) |
155 |
+- { return other.m_dev == m_dev && other.m_ino == m_ino; } |
156 |
+- }; |
157 |
+- StatIdent m_last; |
158 |
+- |
159 |
+- static StatIdent identify(const char *path) |
160 |
+- { |
161 |
+- QT_STATBUF data; |
162 |
+- return QT_STAT(path, &data) == -1 ? StatIdent() : StatIdent(data); |
163 |
+- } |
164 |
+- |
165 |
+- static QByteArray etcLocalTime() |
166 |
+- { |
167 |
+- // On most distros /etc/localtime is a symlink to a real file so extract |
168 |
+- // name from the path |
169 |
+- const QLatin1String zoneinfo("/zoneinfo/"); |
170 |
+- QString path = QStringLiteral("/etc/localtime"); |
171 |
+- long iteration = getSymloopMax(); |
172 |
+- // Symlink may point to another symlink etc. before being under zoneinfo/ |
173 |
+- // We stop on the first path under /zoneinfo/, even if it is itself a |
174 |
+- // symlink, like America/Montreal pointing to America/Toronto |
175 |
+- do { |
176 |
+- path = QFile::symLinkTarget(path); |
177 |
+- int index = path.indexOf(zoneinfo); |
178 |
+- if (index >= 0) // Found zoneinfo file; extract zone name from path: |
179 |
+- return path.midRef(index + zoneinfo.size()).toUtf8(); |
180 |
+- } while (!path.isEmpty() && --iteration > 0); |
181 |
+- |
182 |
+- return QByteArray(); |
183 |
+- } |
184 |
+- |
185 |
+- static QByteArray etcTZ() |
186 |
+- { |
187 |
+- // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ: |
188 |
+- const QString path = QStringLiteral("/etc/TZ"); |
189 |
+- QFile zone(path); |
190 |
+- if (zone.open(QIODevice::ReadOnly)) |
191 |
+- return zone.readAll().trimmed(); |
192 |
+- |
193 |
+- return QByteArray(); |
194 |
+- } |
195 |
+- |
196 |
+- // Any chain of symlinks longer than this is assumed to be a loop: |
197 |
+- static long getSymloopMax() |
198 |
+- { |
199 |
+-#ifdef SYMLOOP_MAX |
200 |
+- // If defined, at runtime it can only be greater than this, so this is a safe bet: |
201 |
+- return SYMLOOP_MAX; |
202 |
++#if defined(SYMLOOP_MAX) |
203 |
++ return SYMLOOP_MAX; // if defined, at runtime it can only be greater than this, so this is a safe bet |
204 |
+ #else |
205 |
+- errno = 0; |
206 |
+- long result = sysconf(_SC_SYMLOOP_MAX); |
207 |
+- if (result >= 0) |
208 |
+- return result; |
209 |
+- // result is -1, meaning either error or no limit |
210 |
+- Q_ASSERT(!errno); // ... but it can't be an error, POSIX mandates _SC_SYMLOOP_MAX |
211 |
+- |
212 |
+- // therefore we can make up our own limit |
213 |
+-# ifdef MAXSYMLINKS |
214 |
+- return MAXSYMLINKS; |
215 |
++ errno = 0; |
216 |
++ long result = sysconf(_SC_SYMLOOP_MAX); |
217 |
++ if (result >= 0) |
218 |
++ return result; |
219 |
++ // result is -1, meaning either error or no limit |
220 |
++ Q_ASSERT(!errno); // ... but it can't be an error, POSIX mandates _SC_SYMLOOP_MAX |
221 |
++ |
222 |
++ // therefore we can make up our own limit |
223 |
++# if defined(MAXSYMLINKS) |
224 |
++ return MAXSYMLINKS; |
225 |
+ # else |
226 |
+- return 8; |
227 |
++ return 8; |
228 |
+ # endif |
229 |
+ #endif |
230 |
+- } |
231 |
+-}; |
232 |
+ } |
233 |
+ |
234 |
++// TODO Could cache the value and monitor the required files for any changes |
235 |
+ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const |
236 |
+ { |
237 |
+ // Check TZ env var first, if not populated try find it |
238 |
+@@ -1256,9 +1136,28 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const |
239 |
+ else if (ianaId.startsWith(':')) |
240 |
+ ianaId = ianaId.mid(1); |
241 |
+ |
242 |
++ // On most distros /etc/localtime is a symlink to a real file so extract name from the path |
243 |
++ if (ianaId.isEmpty()) { |
244 |
++ const QLatin1String zoneinfo("/zoneinfo/"); |
245 |
++ QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime")); |
246 |
++ int index = -1; |
247 |
++ long iteration = getSymloopMax(); |
248 |
++ // Symlink may point to another symlink etc. before being under zoneinfo/ |
249 |
++ // We stop on the first path under /zoneinfo/, even if it is itself a |
250 |
++ // symlink, like America/Montreal pointing to America/Toronto |
251 |
++ while (iteration-- > 0 && !path.isEmpty() && (index = path.indexOf(zoneinfo)) < 0) |
252 |
++ path = QFile::symLinkTarget(path); |
253 |
++ if (index >= 0) { |
254 |
++ // /etc/localtime is a symlink to the current TZ file, so extract from path |
255 |
++ ianaId = path.midRef(index + zoneinfo.size()).toUtf8(); |
256 |
++ } |
257 |
++ } |
258 |
++ |
259 |
++ // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ: |
260 |
+ if (ianaId.isEmpty()) { |
261 |
+- thread_local static ZoneNameReader reader; |
262 |
+- ianaId = reader.name(); |
263 |
++ QFile zone(QStringLiteral("/etc/TZ")); |
264 |
++ if (zone.open(QIODevice::ReadOnly)) |
265 |
++ ianaId = zone.readAll().trimmed(); |
266 |
+ } |
267 |
+ |
268 |
+ // Give up for now and return UTC |
269 |
+@@ -1268,4 +1167,28 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const |
270 |
+ return ianaId; |
271 |
+ } |
272 |
+ |
273 |
++bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const |
274 |
++{ |
275 |
++ return tzZones->contains(ianaId); |
276 |
++} |
277 |
++ |
278 |
++QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const |
279 |
++{ |
280 |
++ QList<QByteArray> result = tzZones->keys(); |
281 |
++ std::sort(result.begin(), result.end()); |
282 |
++ return result; |
283 |
++} |
284 |
++ |
285 |
++QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const |
286 |
++{ |
287 |
++ // TODO AnyCountry |
288 |
++ QList<QByteArray> result; |
289 |
++ for (auto it = tzZones->cbegin(), end = tzZones->cend(); it != end; ++it) { |
290 |
++ if (it.value().country == country) |
291 |
++ result << it.key(); |
292 |
++ } |
293 |
++ std::sort(result.begin(), result.end()); |
294 |
++ return result; |
295 |
++} |
296 |
++ |
297 |
+ QT_END_NAMESPACE |
298 |
+-- |
299 |
+2.28.0 |
300 |
+ |
301 |
|
302 |
diff --git a/dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch |
303 |
new file mode 100644 |
304 |
index 00000000..611c979a |
305 |
--- /dev/null |
306 |
+++ b/dev-qt/qtcore/files/qtcore-5.15.1-timezone-2.patch |
307 |
@@ -0,0 +1,47 @@ |
308 |
+From ffc9093a199a542791920b30d1835c3248920aa0 Mon Sep 17 00:00:00 2001 |
309 |
+From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o> |
310 |
+Date: Sat, 10 Oct 2020 19:26:35 +0200 |
311 |
+Subject: [PATCH 2/2] Revert "Purge two old time-zone lookup fallbacks" |
312 |
+ |
313 |
+This reverts commit b0383cbd388336f698ceeac11a4f50cdff931dd9. |
314 |
+--- |
315 |
+ src/corelib/time/qtimezoneprivate_tz.cpp | 23 +++++++++++++++++++++++ |
316 |
+ 1 file changed, 23 insertions(+) |
317 |
+ |
318 |
+diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp |
319 |
+index 01f9a6cce0..eea6f5e962 100644 |
320 |
+--- a/src/corelib/time/qtimezoneprivate_tz.cpp |
321 |
++++ b/src/corelib/time/qtimezoneprivate_tz.cpp |
322 |
+@@ -1153,6 +1153,29 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const |
323 |
+ } |
324 |
+ } |
325 |
+ |
326 |
++ // On Debian Etch up to Jessie, /etc/localtime is a copy of the relevant |
327 |
++ // zoneinfo file, whose name is recorded in /etc/timezone: |
328 |
++ if (ianaId.isEmpty()) { |
329 |
++ QFile tzif(QStringLiteral("/etc/timezone")); |
330 |
++ if (tzif.open(QIODevice::ReadOnly)) |
331 |
++ ianaId = tzif.readAll().trimmed(); |
332 |
++ } |
333 |
++ |
334 |
++ // On some Red Hat distros /etc/localtime is real file with name held in /etc/sysconfig/clock |
335 |
++ // in a line like ZONE="Europe/Oslo" or TIMEZONE="Europe/Oslo" |
336 |
++ if (ianaId.isEmpty()) { |
337 |
++ QFile tzif(QStringLiteral("/etc/sysconfig/clock")); |
338 |
++ if (tzif.open(QIODevice::ReadOnly)) { |
339 |
++ while (ianaId.isEmpty() && !tzif.atEnd()) { |
340 |
++ const QByteArray line(tzif.readLine().trimmed()); |
341 |
++ if (line.startsWith("ZONE=")) |
342 |
++ ianaId = line.mid(6, line.length() - 7); |
343 |
++ else if (line.startsWith("TIMEZONE=")) |
344 |
++ ianaId = line.mid(10, line.length() - 11); |
345 |
++ } |
346 |
++ } |
347 |
++ } |
348 |
++ |
349 |
+ // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ: |
350 |
+ if (ianaId.isEmpty()) { |
351 |
+ QFile zone(QStringLiteral("/etc/TZ")); |
352 |
+-- |
353 |
+2.28.0 |
354 |
+ |
355 |
|
356 |
diff --git a/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild b/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild |
357 |
index f5dae178..23956275 100644 |
358 |
--- a/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild |
359 |
+++ b/dev-qt/qtcore/qtcore-5.15.2.9999.ebuild |
360 |
@@ -42,7 +42,10 @@ QT5_GENTOO_PRIVATE_CONFIG=( |
361 |
!:xml |
362 |
) |
363 |
|
364 |
-PATCHES=( "${FILESDIR}/${PN}-5.14.1-cmake-macro-backward-compat.patch" ) # bug 703306 |
365 |
+PATCHES=( |
366 |
+ "${FILESDIR}"/${PN}-5.14.1-cmake-macro-backward-compat.patch # bug 703306 |
367 |
+ "${FILESDIR}"/${PN}-5.15.1-timezone-{1,2}.patch # bug 737914 |
368 |
+) |
369 |
|
370 |
pkg_pretend() { |
371 |
use kernel_linux || return |