When upgrading a native Node addon from C++ and NAN to C and N-API, I noticed that libuv's UV_FS_O_DIRECT changes from 16384 to 0.
Is there something that needs to be fixed so that C source files including #include <uv.h> have UV_FS_O_DIRECT initialized correctly? Something like the following in libuv's unix.h?
#define _GNU_SOURCE
#include <fcntl.h>
Looks like you need to define _GNU_SOURCE indeed:
The O_DIRECT, O_NOATIME, O_PATH, and O_TMPFILE flags are Linux-
specific. One must define _GNU_SOURCE to obtain their definitions.
From: http://man7.org/linux/man-pages/man2/open.2.html
But I wonder why it isn't already working though. Calling in the expert :-) /cc @bnoordhuis
That's a bug in our headers, you shouldn't have to define _GNU_SOURCE (or _DEFAULT_SOURCE) to get the proper definition.
(And the headers shouldn't define it themselves because that's unhygienic, it affects the libuv consumer.)
Unfortunately the value of O_DIRECT is architecture-dependent so we'll probably end up with code that looks like this:
#if defined(O_DIRECT)
# define UV_FS_O_DIRECT O_DIRECT
#elif defined(__linux__) && defined(__mips__)
# define UV_FS_O_DIRECT 0x8000
#elif defined(__linux__) && defined(__powerpc__)
# define UV_FS_O_DIRECT 0x4000
// etc.
#else
# define UV_FS_O_DIRECT 0
#endif
Thanks @saghul and @bnoordhuis
I had a bad feeling about _GNU_SOURCE.
@bnoordhuis , would you like me to do a PR exactly as you have it or would you prefer to do it if we need more platforms?
Linux is the only problematic platform, I think, so it's just a matter of filling out the list.
After thinking about it some more, it's probably best to put the linux+arch combos before the #if defined(O_DIRECT) stanza.
Linux is the only problematic platform, I think, so it's just a matter of filling out the list.
If you can give me the values for the various Linux architectures, I don't mind filling out the list.
After thinking about it some more, it's probably best to put the linux+arch combos before the #i defined(O_DIRECT) stanza.
@bnoordhuis, just so I share your reasoning, may I ask why? Is it to ensure that C++ and C addons always define O_DIRECT in exactly the same way?
@jorangreef That's right. Better unconditionally wrong than conditionally right - the former gets detected quicker.