2015-02-16 50 views
5

È la prima volta che lavoro con posix; Ho incluso:S_IFMT e S_IFREG undefined con -std = c11 o -std = gnu11

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

E ho questo frammento.

stat(pathname, &sb); 
if ((sb.st_mode & S_IFMT) == S_IFREG) { 
    /* Handle regular file */ 
} 

Ma usando GCC 4.8.3 su Gentoo se ho compilato con -std = C99 o C11 = -std o -std = gnu99 o -std = gnu11 ho ottenuto questo errore:

error: ‘S_ISFMT’ undeclared (first use in this function) 

Se ometto -std = * non ho errori. Ma voglio anche tutte le caratteristiche di -std = c99 (come la parola chiave restrict o for (int i ;;) ecc ...) Come posso compilare il mio codice?

+0

Questo è un po 'strano. Puoi per favore costruire un esempio di auto-contenuto minimo in modo da poter riprodurre questo problema sul mio sistema? Non ero in grado di riprodurlo altrimenti. – fuz

risposta

5

I moderni sistemi conformi a POSIX sono necessari per fornire i valori S_IFMT e S_IFREG. L'unica versione di POSIX che non richiede questo (e infatti lo proibisce) è POSIX.1-1990, che sembra essere lo standard sulla tua macchina.

In ogni caso, ogni sistema compatibile con POSIX fornisce macros che consente di verificare il tipo di file. Queste macro sono equivalenti al metodo di mascheramento.

Quindi nel tuo caso, invece di (sb.st_mode & S_IFMT) == S_IFREG, scrivi S_ISREG(sb.st_mode).

+0

Questo non risponde alla domanda '__S_IFMT' e' __S_IFREG' sono costanti interne che non dovrebbero mai essere usate da un programma utente. Inoltre, OP chiede di POSIX e tu dai una non risposta specifica della piattaforma. – fuz

+0

@FUZxxl La prima parte della mia risposta * fa * risponde alla domanda, la seconda parte della mia risposta è solo per il caso in cui OP è davvero (e inutilmente) insistente nel fare il mascheramento stesso. –

+0

@FUZxxl L'OP potrebbe anche prendere i valori numerici delle costanti interne e solo usarle nel suo programma, ma è solo inutile perché i sistemi POSIX macros che fanno il mascheramento per te (come spiegato nella mia risposta non specifica della piattaforma). –

1

Mettere sia #define _BSD_SOURCE o #define _XOPEN_SOURCEprima qualsiasi #include nel codice sorgente. Per capire perché funziona, guarda sopra lo #define S_IFMT __S_IFMT in sys/stat.h, quindi nella pagina man feature_test_macros(7).