2016-01-24 22 views
7

Il errno valore ERANGE è documentata da POSIX comeQual è la differenza semantica tra ERANGE ed EOVERFLOW?

Risultato troppo grande.

e EOVERFLOW è documentato come

valore troppo grande per essere memorizzato in tipo di dati.

Qual è la differenza semantica tra questi due? Soprattutto se si considera che lo standard ERANGE viene utilizzato da ISO 9899 (ad esempio in strtol) con la semantica descritta per EOVERFLOW. Questi due valori errno sono distinti solo per motivi storici?

Effettuare il backup degli argomenti con le fonti appropriate, se possibile.

+0

Suggerire di restituire il favore di un'origine appropriata con "EOVERFLOW' è documentato come ..." poiché "ERANGE" nella specifica C11 e "EOVERFLOW" non lo è. – chux

+0

@chux Ecco perché dico "documentato da ** POSIX ** come". La pagina specifica è [errno.h] (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html) . ISO 9899 non documenta il significato di 'ERANGE'. – fuz

+0

Vedo - non ho letto "POSIX" per applicare alla seconda riga. - Certamente ha senso leggere come hai postato/commentato. – chux

risposta

4

SingleUnix è abbastanza dettagliato su EOVERFLOW:

valore troppo grande per essere memorizzato in tipo di dati L'ID utente o il gruppo ID di un oggetto IPC o un file system era troppo grande per essere memorizzato nella appropriata membro del struttura fornita dal chiamante. Questo errore si verifica solo su implementazioni che supportano un intervallo più ampio di ID utente o valori di ID gruppo rispetto a quanto può supportare il membro della struttura dichiarato. Ciò si verifica in genere perché l'oggetto IPC o file system risiede su una macchina remota con un valore maggiore del tipo uid_t, off_t o gid_t rispetto al sistema locale.

EOVERFLOW sembra essere destinato a segnalare un'incompatibilità sottosistema, cioè qualche sistema restituito un valore maggiore di un altro sottosistema può gestire.

EOVERFLOW è explained in more detail nella logica:

La maggior parte degli usi di questo codice di errore sono legati al supporto di file di grandi dimensioni. In genere, questi casi si verificano su sistemi che supportano più ambienti di programmazione con dimensioni diverse per off_t, ma possono verificarsi anche in connessione con file system remoti.

Inoltre, quando diversi ambienti di programmazione hanno larghezze diverse per tipi come int e uid_t, diverse funzioni possono incontrare una condizione in cui un valore in un particolare ambiente è troppo ampio per essere rappresentato. In tal caso, questo errore dovrebbe essere sollevato. Ad esempio, supponiamo che il processo attualmente in esecuzione abbia int a 64 bit e che il descrittore di file 9223372036854775807 sia aperto e non abbia il flag di close-on-exec impostato. Se il processo utilizza execl() per eseguire un file compilato in un ambiente di programmazione con int a 32 bit, la chiamata a execl() può fallire con errno impostato su [EOVERFLOW]. Un errore simile può verificarsi con execl() se uno qualsiasi degli ID utente o uno qualsiasi degli ID di gruppo da assegnare alla nuova immagine di processo non rientra nell'intervallo per l'ambiente di programmazione del file eseguito.

Si noti, tuttavia, che questa condizione non può verificarsi per funzioni che sono esplicitamente descritte come sempre riuscite, come getpid().

Grazie alla @rici per il puntatore

ERANGE è più simile questo non potrà mai andare bene. strtol() è un esempio. Un altro, meno chiaro: Cercando di incrementare un semaforo SYSV oltre i limiti restituiti configurati ERANGE.

Con EOVERFLOW i dati sono lì, semplicemente non si adattano alle strutture dati locali.

Ad esempio, lseek() può restituire EOVERFLOW. Ciò accade, ad es. quando off_t è solo a 32 bit ma il file system può supportare file più grandi e si tenta di cercare oltre la gamma che il sistema operativo può gestire. Perché non è questo ERANGE? Poiché il sistema è in grado di gestire l'operazione in linea di principio, non può restituirla nel tipo di dati disponibile.

Provare a mappare più di 2G utilizzando mmap() su un sistema a 32 bit su Linux restituisce un EOVERFLOW (altri sistemi restituiscono EINVAL).

Sfortunatamente, questo non è del tutto coerente. Ad esempio, lo stack bluetooth restituisce EOVERFLOW quando trova troppi controller host nel sistema.

+1

C'è ancora più spiegazione nel razionale (http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html#tag_22_02_03), che rileva anche che l'errore "ERANGE" è stato aggiunto perché è usato nel Standard C L'esempio nella logica di un eseguibile 'execl' a 64-bit un binario a 32-bit con un fd non compreso non compreso è affascinante. Non ho idea se ciò accada. – rici

+0

@rici Grazie per il riferimento, aggiungerò la citazione – dhke

+0

@rici L'esempio in sé è un po 'ridicolo, ma quello che può e succede è che le persone cercano di eseguire un programma a 32 bit con un descrittore di file aperto in un file di grandi dimensioni sui sistemi dove i file di grandi dimensioni vengono implementati solo per i programmi a 64 bit. – fuz

4

C'è una differenza semantica:

EOVERFLOW viene utilizzato per il caso in cui una dimensione os di buffer troppo piccolo e il trasferimento dei dati richiesta dovrebbe overflow del buffer di destinazione, o condizioni di errore simili:

http://man7.org/linux/man-pages/man2/open_by_handle_at.2.html

EOVERFLOW

  The handle->handle_bytes value passed into the call was too 
      small. When this error occurs, handle->handle_bytes is 
      updated to indicate the required size for the handle. 

http://man7.org/linux/man-pages/man2/open.2.html

EOVERFLOW

  pathname refers to a regular file that is too large to be 
      opened. The usual scenario here is that an application 
      compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 
      tried to open a file whose size exceeds (1<<31)-1 bytes; see 
      also O_LARGEFILE above. This is the error specified by 
      POSIX.1; in kernels before 2.6.24, Linux gave the error EFBIG 
      for this case. 

ERANGE viene utilizzato per valori che non rientrano nel tipo di destinazione (C99) e per argomenti fuori dell'intervallo definito per i comandi specifici (POSIX)

Ma è anche utilizzato negli errori in cui EOVERFLOW sarebbe più appropriato:

http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html

The pthread_setname_np() function can fail with the following error: 

ERANGE The length of the string specified pointed to by name exceeds 
      the allowed limit. 

    The pthread_getname_np() function can fail with the following error: 

    ERANGE The buffer specified by name and len is too small to hold the 
      thread name. 

Credo EOVERFLOW viene utilizzato per le chiamate di sistema e ERANGE viene utilizzato in funzioni di libreria C, standard e non.

Problemi correlati