Eina from EFL incompatible with ftw.h? - c

I tried to play with the file module of the Eina library and the classical system calls.
My problem is when I want to use eina and some functions and constants from ftw.h.
Here is the first simple code:
#define _XOPEN_SOURCE 500 /*Get nftw() and S_IFSOCK declarations*/
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <Eina.h>
/*Compile with
gcc -o eina_ftw eina_ftw.c $(pkg-config --libs --cflags eina)
*/
int main(int argc, char **argv)
{
int a = FTW_DNR;
int b=0;
b = FTW_MOUNT;
printf("ok\n");
exit(EXIT_SUCCESS);
}
When I compile it I have those errors:
In file included from /usr/include/eina-1/eina/eina_lock.h:50:0,
from /usr/include/eina-1/Eina.h:259,
from eina_ftw.c:5:
/usr/include/eina-1/eina/eina_inline_lock_posix.x:57:1: erreur: unknown type name thread_spinlock_t’
typedef pthread_spinlock_t Eina_Spinlock;
^
/usr/include/eina-1/eina/eina_inline_lock_posix.x:561:4: erreur: unknown type name ‘pthread_barrier_t’
pthread_barrier_t barrier;
^
Ok so I tried this:
#include <Eina.h>
#define _XOPEN_SOURCE 500 /*Get nftw() and S_IFSOCK declarations*/
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
/*Compile with
gcc -o eina_ftw eina_ftw.c $(pkg-config --libs --cflags eina)
*/
int main(int argc, char **argv)
{
int a = FTW_DNR;
int b=0;
b = FTW_MOUNT;
printf("ok\n");
exit(EXIT_SUCCESS);
}
And now I have this kind of error:
eina_ftw.c: In function ‘main’:
eina_ftw.c:13:7: erreur: ‘FTW_MOUNT’ undeclared (first use in this function)
b = FTW_MOUNT;
^
eina_ftw.c:13:7: note: each undeclared identifier is reported only once for each function it appears in
So I would like to know if there is a way to solve this problem?

Setting _XOPEN_SOURCE 500 is (approximately equivalent to) asking for the 1995 POSIX declarations.
Set it to at least 600 (for POSIX 2001) or perhaps 700 (for POSIX 2008).
Strictly, of course, setting _XOPEN_SOURCE is asking for a particular version of the Open Group (originally X/Open) Single Unix Specification, but there is a strong relationship between the POSIX standard and the Open Group standard. You can find out more at:
The Open Group Base Specifications Issue 7, IEEE Std 1003.1™, 2013 Edition
The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
Single UNIX® Specification, Version 2, 1997

Related

How to know to which value I should define _POSIX_C_SOURCE?

Let's say for instance I want to use the structure timespec, which is defined in time.h. According to the manpages I only need to include time.h. But when compiling in c99, this isn't enough:
#include <stdio.h>
#include <time.h>
struct timespec abcd;
int main(int argc, char *argv[])
{
return 0;
}
According to the info I find online (not in the manpages), I need to add this:
#define _POSIX_C_SOURCE 200809L
So I have a few questions:
How do I know to which value I need _POSIX_C_SOURCE to be equal? I found multiple values online.
Why does the placement of this definition influence the compilation? (cf . infra)
#include <stdio.h>
#define _POSIX_C_SOURCE 200809L
#include <time.h>
struct timespec abcd;
int main(int argc, char *argv[])
{
return 0;
}
$ gcc test.c -Wall -Wpedantic -std=c99 -o test
test.c:9:25: error: field ‘time_last_package’ has incomplete type
struct timespec time_last_package;
compiles well:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <time.h>
....
Thanks
How do I know to which value I need _POSIX_C_SOURCE to be equal? I found multiple values online.
There is one value per POSIX standard definition. So you can use any value which:
defines the functionality you need
is supported by your hosting OS
Best is to use the lowest value that meet both those criteria.
Why does the placement of this definition influence the compilation?
POSIX says :
System Interface Chapter 2. Section 2 The Compilation Environment: A POSIX-conforming application should ensure that the feature test
macro _POSIX_C_SOURCE is defined before inclusion of any header.
Otherwise it may leads to wrong/incompatible included definitions... Defining it before any include ensure that all is under the same POSIX version...
Recommended reading : The Open Group Base Specifications Issue 7, 2018 edition, 2 - General Information
The other answer gives nice background. But, it's also possible to define this at the compiler level so you don't have to put it in your source. With gcc and glibc at least, the command-line option
-D_POSIX_C_SOURCE=199309L
is enough to ensure that nanosleep and struct timespec are available if you include <time.h>.

redefinition of 'struct timeval' in several headers

I have several issues to compile a C program to stream sound from Intel Edison to devices (iOS and Android).
I made a C program :
I use alsa/asoundlib.h and pthread.h in my program I don't include sys/time.h because ALSA does not allow this.
I use lot of timeval in my program, when i compile it on my computer i'ts compile fine, but on my edison when I :
gcc -std=c99 -Wall -O0 -ggdb -o sender sender.c spsc_circular_queue.c -lopus -lasound -lpthread
In file included from /usr/include/alsa/asoundlib.h:49:0,
from sender.c:16:
/usr/include/alsa/global.h:145:8: error: redefinition of 'struct timespec'
struct timespec {
^
In file included from /usr/include/alsa/global.h:34:0,
from /usr/include/alsa/asoundlib.h:49,
from sender.c:16:
/usr/include/time.h:120:8: note: originally defined here
struct timespec
^
In file included from /usr/include/time.h:41:0,
from /usr/include/sched.h:34,
from sender.c:18:
/usr/include/bits/time.h:30:8: error: redefinition of 'struct timeval'
struct timeval
^
In file included from /usr/include/alsa/asoundlib.h:49:0,
from sender.c:16:
/usr/include/alsa/global.h:140:8: note: originally defined here
struct timeval {
^
Makefile:16: recipe for target 'sender' failed
make: *** [sender] Error 1
How can I manage to stop these redifinitions ?!
Thank you for your help !
Extra info:
I include :
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <alloca.h>
#include <limits.h>
#include <inttypes.h>
#include <alsa/asoundlib.h>
#include "../opus/include/opus.h"
#include <pthread.h>
#include "spsc_circular_queue.h"
I remove sched.h, nothing happen
ALSA depends on types struct timespec and struct timeval. Its global.h header therefore appropriately does this:
/* for timeval and timespec */
#include <time.h>
However, it seems to be of the opinion that GLIBC defines those structures only when an appropriate feature-test macro has been defined, for that header also says:
#ifdef __GLIBC__
#if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE)
struct timeval {
time_t tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif
#endif
It's hard to determine under what circumstances GLIBC actually does declare the wanted structures. It indeed does do so conditionally, but it appears that the conditions, at least in GLIBC v2.17, are more general than ALSA assumes. Thus ALSA seems to have fallen out of sync with GLIBC, if indeed it ever was perfectly synchronized in the first place, and under some conditions it produces the duplicate declaration problem you encountered.
Your best bet is probably to define the _POSIX_C_SOURCE macro when you compile. The values supported by GLIBC are documented on the linked manual page. Any value, except possibly 0, ought to solve the problem for you, but the effects will be broader, so you may need to experiment with different values. To start, I suggest the value 200809L, which is the most inclusive among the values supported by GLIBC:
gcc -D_POSIX_C_SOURCE=200809L -std=c99 -Wall -O0 -ggdb -o sender sender.c spsc_circular_queue.c -lopus -lasound -lpthread
ALSA should then rely on the system's definitions instead of issuing its own, duplicate ones.

Implicit declaration of function ‘mknod’ but I have the headers included

I am trying to make a C program that uses named pipes to communicate with a C++ program on a Raspberry Pi 3.
The warning that GCC is spitting out when I compile some code of mine:
/home/pi/BluetoothTest/btooth.c|76|warning: implicit declaration of function ‘mknod’ [-Wimplicit-function-declaration]|
Here is the code from for the function, including the #if above it:
#if defined __USE_MISC || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
extern int mknod (const char *__path, __mode_t __mode, __dev_t __dev)
__THROW __nonnull ((1));
and here are the includes that I have in the file:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
//#include <linux/stat.h>
The program attempts to create the pipe here:
umask(0);
fifo = mknod(PIPE_LOC, S_IFIFO|0666, 0);
fp = fopen(PIPE_LOC, "w");
fifo is an int that isn't used anywhere else and fp is a FILE* to the pipe. Some debugging that I have done shows that fifo has a value of -1 after mknod runs, likely because of the compiler not seeming to be able to find the implementation of the function.
How do I make it so that GCC knows where to find the implementation of mknod?
As you can see that for declaration of mknod() function to stay after preprocessing stage, one of three macros (__USE_MISC, __USE_BSD, __USE_XOPEN_EXTENDED) should be defined. Otherwise, declaration of mknod() will be removed during preprocessing stage.
#if defined __USE_MISC || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
extern int mknod (const char *__path, __mode_t __mode, __dev_t __dev)
__THROW __nonnull ((1));
You can use compiler options: -std=gnu99 -D_GNU_SOURCE or you can define these macros on your own and place them above header file inclusion.
I think you're missing a definition of some feature test macro required for the respective headers to define mknod. According to the Linux Programmer's Manual for the function (man 2 mknod) the macros for glibc are:
mknod():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.19: */ _DEFAULT_SOURCE
|| /* Glibc versions <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE
Try adding -D_XOPEN_SOURCE=500 to your compile flags to see if that helps.

why am i not able to declare sigset_t with std=c99?

If i compile the below program with std=c99, i get an error, but the program compiles fine without the c99 flag. Why?
#include <signal.h>
void x()
{
sigset_t dd;
}
int main(void)
{
x();
return 0;
}
jim#cola temp]$ gcc -std=c99 blah.c -o blah
blah.c: In function ‘x’:
blah.c:9: error: ‘sigset_t’ undeclared (first use in this function)
blah.c:9: error: (Each undeclared identifier is reported only once
blah.c:9: error: for each function it appears in.)
blah.c:9: error: expected ‘;’ before ‘dd’
Because sigset_t is not part of <signal.h> in standard C and you requested strict standards compatibility with -std=c99. That is, a strictly standard C program can do:
#include <signal.h>
int sigset_t;
int main(void) { return 0; }
and expect it to work.
sigset_t is not in C99 standard, but it is available in POSIX. You can define _POSIX_SOURCE or _POSIX_C_SOURCE to make sigset_t available.
Here is the definition:
#define _NSIG 64
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef unsigned long old_sigset_t; /* at least 32 bits */
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
Also see What does #define _POSIX_SOURCE mean?

Warning with nftw

I'm trying to use the nftw to process some files under a directory
#include <ftw.h>
#include <stdio.h>
int wrapper(const char * fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
printf("File %d\n", ftwbuf->base);
return(0);
}
int main(int argc, char ** argv) {
const char *name;
int flags = 0;
name = argv[1];
nftw(name, wrapper, 20, flags);
return 0;
}
When I'm compiling (gcc kconfig_parser.c -o parser) , I've got this warning and this error..
kconfig_parser.c:5: warning: ‘struct FTW’ declared inside parameter list
kconfig_parser.c:5: warning: its scope is only this definition or declaration, which is probably not what you want
kconfig_parser.c: In function ‘wrapper’:
kconfig_parser.c:6: error: dereferencing pointer to incomplete type
I've checked the definition of the struct and the prototype of the callback, and some examples, it should be fine... What am I doing wrong ? (I've removed almost everything of my code to clear it)...
thanks
Linux, for some reason, still uses SUSv1 for this API, where nftw() is still considered an extension.
From the Linux manual page, the include has to be:
#define _XOPEN_SOURCE 500
#include <ftw.h>
Hmm. Your code works for me. Check your include paths, maybe? Though this is a system header, so it should be pretty hard to miss this. Or were you accidentally compiling a version that didn't have the #include <ftw.h> line?
$ gcc -o ftw ftw.c
$ ./ftw my-directory
File 10
File 11
File 16
File 16
File 16
File 16
File 16
... etc ...
edit: The test above was done on Mac OS X. In a (now deleted) comment the OP mentioned he was on Debian, for which the man page mentions that #define _XOPEN_SOURCE 500 is necessary, as Juliano points out.
On a CentOs versions the header file didn't use "#define _XOPEN_SOURCE 500"
i had to do this below,
#define __USE_XOPEN_EXTENDED 1
#include <ftw.h>
On Ubuntu 18.04, this is what seems to work now (similar to CentOS as mentioned by JohnMeg).
#define __USE_XOPEN_EXTENDED 1
#include <ftw.h>

Resources