A quanto pare no, non è possibile. Tanto per cominciare, c'è solo un time()
funzione in Linux, no time32()
o time64()
.
Dopo aver cercato per un po', posso vedere che non è colpa di libc, ma il colpevole è in realtà il kernel.
Affinché libc recuperi l'ora corrente, deve eseguire una chiamata di sistema:
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
La chiamata di sistema è definita come:
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
La funzione get_seconds()
restituisce un unsigned long
, in questo modo:
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
E timekeeper.xtime_sec
è in realtà a 64 bit:
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
Ora, se conosci la tua C, sai che la dimensione di unsigned long
è in realtà dipendente dall'implementazione. Sulla mia macchina a 64 bit qui, è a 64 bit; ma sulla mia macchina a 32 bit qui, è a 32 bit. È forse potrebbe essere a 64 bit su alcune implementazioni a 32 bit, ma non c'è alcuna garanzia.
D'altra parte, u64
è sempre a 64 bit, quindi alla base il kernel tiene traccia del tempo in un tipo a 64 bit. Perché poi procede a restituire questo come un unsigned long
, che non è garantito che sia lungo 64 bit, è al di là di me.
Alla fine, anche se le libc forzassero time_t
per mantenere un valore a 64 bit, non cambierebbe nulla.
Potresti legare profondamente la tua applicazione al kernel, ma non penso che ne valga la pena.
Molte risposte sopra dicevano che questo è impossibile, ma questo è completamente errato . Era non era possibile in quel momento, ma la gente parlava di aggiustarlo da anni. Finalmente il supporto dell'ora a 64 bit su piattaforme a 32 bit è stato introdotto nel kernel Linux 5.1 con l'aggiunta del nuovo *time64
syscalls. Guarda questa tabella puoi vedere che quelle chiamate di sistema sono disponibili solo su piattaforme a 32 bit. Ora, se stai scrivendo codice per sistemi a 32 bit, puoi chiamare clock_gettime64
direttamente (da assembly inline o C con syscall()
) per ottenere l'ora corrente
Tuttavia, dopo sei completamente solo. Se vuoi uno spazio utente completo support devi essere su Linux 5.6 o superiore insieme a musl 1.2+ o glibc 2.32+. Ricostruisci semplicemente il tuo codice e il tuo time_t
diventerà lungo 64 bit
Tutto lo spazio utente deve essere compilato con un
time_t
a 64 bit , che sarà supportato nelle prossime versioni musl-1.2 e glibc-2.32, insieme alle intestazioni del kernel installate da linux-5.6 o successive.Le applicazioni che utilizzano direttamente le interfacce delle chiamate di sistema devono essere portate per utilizzare
time64
syscalls aggiunti in Linux-5.1 al posto delle chiamate di sistema esistenti. Ciò influisce sulla maggior parte degli utenti difutex()
eseccomp()
così come i linguaggi di programmazione che hanno il proprio ambiente di runtime non basato su libc.https://lkml.org/lkml/2020/1/29/355?anz=web
Per ulteriori informazioni
- Ci avviciniamo alla fine del gioco dell'anno 2038 del kernel
- Gestione dei simboli temporali a 64 bit nella libreria GNU C
- Proofness design glibc Y2038
- Modifica time_t e clock_t a 64 bit