2

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?

cyborgdragon
  • 109
  • 6

2 Answers2

2

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.

jotik
  • 17,044
  • 13
  • 58
  • 123
2

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.

abhiarora
  • 9,743
  • 5
  • 32
  • 57
  • 1
    BRAVO! Saved me a truckload of time. I did notice those pre-compiler variable in the headers, but wasn't aware of the one variable to rule them all! -D_GNU_SOURCE. My code was compiling on macOS Sierra but when I built it on RH I was getting that error for popen, getopt, strdup, etc... and your suggestion fixed it! – clearlight Feb 06 '17 at 07:48