GNU/Linux >> Linux Esercitazione >  >> Linux

Esiste un modo per ottenere time_t a 64 bit nei programmi a 32 bit in Linux?

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 di futex() e seccomp() 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

Linux
  1. Conversione timestamp Unix a 64 bit

  2. Ottieni secondi dall'epoca in Linux

  3. C'è un modo per rinominare un progetto Cargo?

  4. Trovare librerie a 32 bit su Linux a 64 bit

  5. Esiste un modo per bloccare LD_PRELOAD e LD_LIBRARY_PATH su Linux?

Come sapere se la versione a 32 bit o 64 bit di Linux

Come verificare il sistema Linux è a 32 o 64 bit?

C'è un modo per ottenere emoji colorati in qualsiasi emulatore di terminale su Linux?

Modalità operativa CPU a 32 bit e 64 bit su Linux

C'è un modo per ottenere la versione del BIOS da Linux?

C'è un modo per ottenere i rapporti Cache Hit/Miss per i dispositivi a blocchi in Linux?