Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

S_IFMT and S_IFREG undefined with -std=c11 or -std=gnu11

Tags:

c

posix

gcc

c11

stat

It's my first time working with posix; I included:

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

And I've this snippet.

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

But using GCC 4.8.3 on Gentoo if I compiled with -std=c99 or -std=c11 or -std=gnu99 or -std=gnu11 I got this error:

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

If I omit -std=* I got no errors. But I want all the features of -std=c99 too (like the keyword restrict or for(int i;;) etc ...) How could I compile my code?

like image 878
Giorgio Napolitano Avatar asked Feb 16 '15 17:02

Giorgio Napolitano


Video Answer


2 Answers

Modern POSIX-compliant systems are required to provide the S_IFMT and S_IFREG values. The only version of POSIX that does not require this (and in fact, forbids it) is POSIX.1-1990, which appears to be the standard on your machine.

In any case, every POSIX-compliant system provides macros that allow you to check the type of the file. These macros are equivalent to the masking method.

So in your case, instead of (sb.st_mode & S_IFMT) == S_IFREG, just write S_ISREG(sb.st_mode).

like image 150
Daniel Kleinstein Avatar answered Oct 03 '22 02:10

Daniel Kleinstein


Put either #define _BSD_SOURCE or #define _XOPEN_SOURCE before any #include in your source code. To see why this works, look right above #define S_IFMT __S_IFMT in sys/stat.h, then in feature_test_macros(7) man page.

like image 21
Peter968475 Avatar answered Oct 03 '22 00:10

Peter968475