It might be a bit late, but I recently encountered the same issue and did some research. Based on your URL reference to fcntl's definition, I noticed it's actually implemented as:
extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64);
Digging deeper, the __REDIRECT
macro uses __asm__ ("xyz")
, a technique that modifies symbol names at the assembly level.
Why not leverage this same approach to bypass glibc's behavior? Here's a code snippet I used:
#if defined (__GLIBC__) && defined (__GNUC__) && defined (__USE_FILE_OFFSET64)
extern int fcntl_legacy(int __fd, int __cmd, ...) __asm__("fcntl");
#else
#define fcntl_legacy fcntl
#endif
inline int set_nonblocking(int fd)
{
int flags = fcntl_legacy(fd, F_GETFL, 0);
if (flags == -1) {
return -1;
}
return fcntl_legacy(fd, F_SETFL, flags | O_NONBLOCK);
}
Tested with -D_FILE_OFFSET_BITS=64 + GCC 14.2.1 + glibc 2.40 on amd64, this successfully redirects the dependency from fcntl64 to the legacy fcntl.