Use of undeclared identifier 'O_DIRECT' - c

Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin18.0.0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define _GNU_SOURCE
#define __USE_GNU 1
#include <fcntl.h>
int main()
{
int fd = open("./test.txt", O_WRONLY|O_DIRECT);
close(fd);
return 0;
}
I use clang -o out test.c and get the following result:
test.c:14:39: error: use of undeclared identifier 'O_DIRECT'
int fd = open("./test.txt", O_WRONLY|O_DIRECT);
How can I solve the problem?
Thank you.

With this snippet it is impossible to tell what you are trying to do, but in general do not use nonstandard stuff in applications intended to be portable.
The portable way to accomplish your task is probably fsync.

To sum up
For LINUX, the O_DIRECT flag has to be included. For Mac OSX, O_DIRECT is not available. Instead, fcntl(fd, F_NOCACHE, 1) looks to be the canonical solution where fd is the file descriptor of the file. For Windows, there is a flag called FILE_FLAG_NO_BUFFERING as the counterpart in Windows of O_DIRECT
Reference here

Related

F_GETPIPE_SZ undeclared

I'm trying to get size of pipe:
printf("pipe 0 size: %d bytes\npipe 1 size: %d bytes\n", fcntl(fd[0], F_GETPIPE_SZ), fcntl(fd[1], F_GETPIPE_SZ));
Used headers (half of them used by another parts of code):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/wait.h>
When I'm trying to compile, gcc fails with this error:
‘F_GETPIPE_SZ’ undeclared (first use in this function)
kernel version - 5.4.0-88-generic
libc6-dev version - 2.31-0ubuntu9.2
gcc version - 4:9.3.0-1ubuntu2
Since this macro is not part of POSIX, you must define the _GNU_SOURCE feature test macro before including <fcntl.h>.
This is stated in the fcntl(2) man page, in the "Conforming To" section.
See What does "#define _GNU_SOURCE" imply?

Can't compile i2c_smbus_write_byte on Raspberry Pi 4

Has anybody tried using the i2c_smbus_write_byte or any similar function on Raspberry Pi 4?
I can't get it compile it fails at the linking with not finding it.
I'm using it as described here: http://synfare.com/599N105E/hwdocs/rpi/rpii2c.html
All the headers recommended are there is and also the -li2c in the Makefile.
Can anybody tell what the problem can be? I have no clue at the moment.
Might be worth checking to see if libi2c-dev is present on your system.
sudo apt-get install libi2c-dev
may be all that you need.
The page you are linking to says:
With the Buster version, as of june 2019, the necessary details for
using i2c_smbus_write_byte_data() and siblings, require the following
include statements:
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
Using fgrep you can confirm that the function is declared in the /usr/include/i2c/smbus.h:
# cd /usr/include; fgrep -R i2c_smbus_write_byte *
i2c/smbus.h:extern __s32 i2c_smbus_write_byte(int file, __u8 value);
i2c/smbus.h:extern __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
So this should work:
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
int main(void) {
int i2c = open("/dev/i2c-1", O_RDWR);
i2c_smbus_write_byte(i2c, 1);
close(i2c);
return 0;
}
I tested that this example compiles successfully in the latest Raspbian Buster Lite:
gcc test.c -otest -li2c
If you are using g++ instead of gcc, then you should wrap the include directives with extern "C":
extern "C" {
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
}

Getting GCC error: "sys/memfd.h: No such file or directory"

I'm trying to use the memfd_create syscall in my C code. I tried to include sys/memfd.h as the man page for memfd_create says is appropriate, but GCC gives me an error "sys/memfd: No such file or directory".
I've tried Googling around and couldn't find anyone having the same problem. I noticed some versions of the manpage for memfd_create say that I should include sys/mman.h, but it didn't seem to help when I tried it. It would say memfd_create was implicitly declared.
Here is a minimal reproduction of my problem.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/memfd.h>
int main(){
int fd;
fd = memfd_create("test", MFD_CLOEXEC);
return 0;
}
I expect the above code to compile and run without error.
On older systems, you'll have to include linux/memfd.h for the MFD_ defines, and call memfd_create() via the the syscall(2) wrapper (and include unistd.h and sys/syscall.h for it work).
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/memfd.h>
#include <err.h>
int main(void){
int fd;
if((fd = syscall(SYS_memfd_create, "test", MFD_CLOEXEC)) == -1)
err(1, "memfd_create");
return 0;
}
The Ubuntu man-pages in Bionic (18.04) are not up to date with this API (including its implementation in Bionic).
The Focal man-page correctly shows how to include memfd_create(). It says:
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sys/mman.h>
So you only need to include <sys/mman.h>, and you need to build with -D_GNU_SOURCE in your compiler flags. Or, do as the man page says and literally #define _GNU_SOURCE before including the header. However, I recommend just compiling with -D_GNU_SOURCE instead.

sem_open doesn't work with Ubuntu : undefined reference to `sem_open'

Given this code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <pthread.h>
#define BUF_SIZE 256
int main()
{
key_t key;
char *virtualaddr;
sem_t *get, *put;
int shmid;
const char* messageOne = "Hello world , I'm child number 1\n";
const char* messageTwo = "Hello world , I'm child number 2\n";
char buf[BUF_SIZE];
key = ftok("anyfile",'R');
shmid = shmget(key,1024,0644|IPC_CREAT);
...
...
shmctl (shmid, IPC_RMID, NULL);
exit(EXIT_SUCCESS);
}
I get from eclipse undefined reference to sem_open .
I've check with this post since this question is very similar to mine , but didn't understand exactly where is my mistake ,
Can you please explain where do I need to fix it / add another compilation command (if this is indeed the case) ?
Much appreciated
You need to include -lpthread when compiling. This is used by the linker, to link your binary against the library.
The other answers already cover how to do this on the command line.
To do this in Eclipse, you need to follow the directions here:
In the project properties, go to : C/C++ Build --> Settings. Then
"Tool Settings", select "Libraries" under "Linker". You can add all
your project libraries there (without the "-l"). Also in the lower
part, you can add custom path to search libraries
When linking, you have to add the flag -pthread or -lrt to the command line. It's right there in the manual page.
As it is written in the first answer in the question you linked, you nedd to compile it in this way:
gcc source.c -lpthread
-lrt or -pthread will do the same.

C warning: implicit declaration of function ‘fchmod’

I have a function, createFile that uses fchmod:
int createFile(char *pFileName) {
int ret;
if ((ret = open(pFileName, O_RDWR | O_CREAT | O_TRUNC)) < 0)
errorAndQuit(2);
fchmod(ret, S_IRUSR | S_IWUSR);
return ret;
}
At the top of my file, I have the following includes:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
When compiling: the compiler spits out:
warning: implicit declaration of function ‘fchmod’
I'm including all of the correct files, yet getting this warning. The program runs fine, even with the warning.
By a happy coincidence, your question is directly answered by the feature_test_macros(7) manpage:
Specification of feature test macro requirements in manual pages
When a function requires that a feature test macro is
defined, the manual page SYNOPSIS typically includes a note
of the following form (this example from the chmod(2) manual
page):
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
Feature Test Macro Requirements for glibc (see
feature_test_macros(7)):
fchmod(): _BSD_SOURCE || _XOPEN_SOURCE >= 500
The || means that in order to obtain the declaration of
fchmod(2) from <sys/stat.h>, either of the following macro
definitions must be made before including any header files:
#define _BSD_SOURCE
#define _XOPEN_SOURCE 500 /* or any value > 500 */
Alternatively, equivalent definitions can be included in the
compilation command:
cc -D_BSD_SOURCE
cc -D_XOPEN_SOURCE=500 # Or any value > 500
You didn't specify what compiler or platform you're using, but on my recent Linux installation, fchmod() is defined in but guarded by a couple of #ifdefs (__USD_BSD and __USE_XOPEN_EXTENDED).
You aren't supposed to set those directly, but rather via the _FOO_SOURCE macros in . Try defining _XOPEN_SOURCE_EXTENDED or just _GNU_SOURCE and recompiling (and note that these macros enable nonstandard functionality and use of the functionality they enable may limit the portability of your code).
I have faced this error while building uml.
Just add this line in the file where this error is thrown:
#include "sys/stat.h"
I believe it will take care about adding the macros defined in the above answers.

Resources