Anscheinend nein, das ist nicht möglich. Für den Anfang gibt es nur einen time()
Funktion unter Linux, kein time32()
oder time64()
.
Nachdem ich eine Weile gesucht habe, kann ich sehen, dass es nicht die Schuld der libc ist, sondern dass der Übeltäter tatsächlich der Kernel ist.
Damit die libc die aktuelle Uhrzeit abrufen kann, muss sie einen Systemaufruf dafür ausführen:
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
Der Systemaufruf ist definiert als:
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
Die Funktion get_seconds()
gibt einen unsigned long
zurück , etwa so:
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
Und timekeeper.xtime_sec
ist eigentlich 64-Bit:
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
Nun, wenn Sie Ihr C kennen, wissen Sie, dass die Größe unsigned long
ist ist tatsächlich implementierungsabhängig. Auf meinem 64-Bit-Rechner hier ist es 64-Bit; aber auf meinem 32-Bit-Rechner hier ist es 32-Bit. Es möglicherweise könnte bei einer 32-Bit-Implementierung 64-Bit sein, aber es gibt keine Garantie.
Andererseits u64
ist immer 64-Bit, also verfolgt der Kernel ganz unten die Zeit in einem 64-Bit-Typ. Warum es dann fortfährt, dies als unsigned long
zurückzugeben , die garantiert nicht 64-Bit lang ist, ist mir ein Rätsel.
Am Ende, selbst wenn libc's time_t
erzwingen würde einen 64-Bit-Wert zu halten, würde es nichts ändern.
Sie könnten Ihre Anwendung tief in den Kernel einbinden, aber ich glaube nicht, dass es das wert ist.
Viele Antworten oben sagten, dass dies unmöglich ist, aber das ist völlig falsch . Es war war damals nicht möglich, aber es wurde schon seit Jahren darüber gesprochen, es zu reparieren. Schließlich wurde die 64-Bit-Zeitunterstützung auf 32-Bit-Plattformen mit dem Hinzufügen des neuen *time64
in den Linux 5.1-Kernel eingeführt Systemaufrufe. In dieser Tabelle sehen Sie, dass diese Systemaufrufe nur auf 32-Bit-Plattformen verfügbar sind. Wenn Sie jetzt Code für 32-Bit-Systeme schreiben, können Sie clock_gettime64
aufrufen direkt (aus Inline-Assembly oder C mit syscall()
), um die aktuelle Uhrzeit zu erhalten
Danach ist man jedoch komplett auf sich allein gestellt. Wenn Sie den vollen Benutzerbereich wollen Unterstützung benötigen Sie Linux 5.6 oder höher zusammen mit Musl 1.2+ oder Glibc 2.32+. Erstellen Sie einfach Ihren Code und Ihren time_t
neu wird 64-Bit lang
Der gesamte Benutzerbereich muss mit einem 64-Bit-
time_t
kompiliert werden , die in den kommenden Releases musl-1.2 und glibc-2.32 unterstützt werden, zusammen mit installierten Kernel-Headern von linux-5.6 oder höher.Anwendungen, die die Systemaufrufschnittstellen direkt verwenden, müssen portiert werden, um den
time64
zu verwenden Systemaufrufe, die in Linux-5.1 anstelle der vorhandenen Systemaufrufe hinzugefügt wurden. Dies betrifft die meisten Benutzer vonfutex()
undseccomp()
sowie Programmiersprachen, die ihre eigene Laufzeitumgebung haben, die nicht auf libc basiert.https://lkml.org/lkml/2020/1/29/355?anz=web
Weitere Informationen
- Annäherung an das Kernel-Jahr-2038-Endspiel
- Behandlung von 64-Bit-Zeitsymbolen in der GNU-C-Bibliothek
- glibc Y2038 Proofness-Design
- Zeit_t und Uhr_t auf 64 Bit ändern