Apparemment, non ce n'est pas possible. Pour commencer, il n'y a qu'un seul time()
fonction sous Linux, pas de time32()
ou time64()
.
Après avoir cherché un moment, je peux voir que ce n'est pas la faute de la libc, mais le coupable est en fait le noyau.
Pour que la libc récupère l'heure actuelle, elle doit exécuter un appel système :
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
L'appel système est défini comme :
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
La fonction get_seconds()
renvoie un unsigned long
, comme ceci :
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
Et timekeeper.xtime_sec
est en fait 64 bits :
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
Maintenant, si vous connaissez votre C, vous savez que la taille de unsigned long
dépend en fait de l'implémentation. Sur ma machine 64 bits ici, c'est 64 bits; mais sur ma machine 32 bits ici, c'est 32 bits. C'est peut-être pourrait être 64 bits sur une implémentation 32 bits, mais il n'y a aucune garantie.
Par contre, u64
est toujours 64 bits, donc à la base, le noyau garde une trace de l'heure dans un type 64 bits. Pourquoi il continue ensuite à renvoyer ceci sous la forme d'un unsigned long
, dont la longueur n'est pas garantie sur 64 bits, me dépasse.
Au final, même si la libc forcerait time_t
pour contenir une valeur 64 bits, cela ne changerait rien.
Vous pourriez lier profondément votre application au noyau, mais je ne pense pas que cela en vaille la peine.
De nombreuses réponses ci-dessus indiquent que c'est impossible, mais c'est entièrement incorrect . C'était c'était pas possible à ce moment-là, mais les gens parlaient de le réparer depuis des années. Enfin, la prise en charge de l'heure 64 bits sur les plates-formes 32 bits a été introduite dans le noyau Linux 5.1 avec l'ajout du nouveau *time64
appels système. Regardez ce tableau, vous pouvez voir que ces appels système ne sont disponibles que sur les plates-formes 32 bits. Maintenant, si vous écrivez du code pour les systèmes 32 bits, vous pouvez appeler clock_gettime64
directement (depuis l'assemblage en ligne ou C avec syscall()
) pour obtenir l'heure actuelle
Cependant, après cela, vous êtes complètement seul. Si vous voulez un espace utilisateur complet vous devez être sur Linux 5.6 ou supérieur avec musl 1.2+ ou glibc 2.32+. Reconstruisez simplement votre code et votre time_t
deviendra 64 bits
Tout l'espace utilisateur doit être compilé avec un
time_t
64 bits , qui sera pris en charge dans les prochaines versions musl-1.2 et glibc-2.32, ainsi que les en-têtes de noyau installés à partir de linux-5.6 ou supérieur.Les applications qui utilisent directement les interfaces d'appel système doivent être portées pour utiliser le
time64
appels système ajoutés dans linux-5.1 à la place des appels système existants. Cela affecte la plupart des utilisateurs defutex()
etseccomp()
ainsi que des langages de programmation qui ont leur propre environnement d'exécution non basé sur libc.https://lkml.org/lkml/2020/1/29/355?anz=web
Pour plus d'informations
- À l'approche de la fin de l'année 2038 du noyau
- Gestion des symboles de temps 64 bits dans la bibliothèque GNU C
- Conception d'épreuve glibc Y2038
- Changez time_t et clock_t en 64 bits