From 958e826b690e10f9d2bf1b2c25f96e3b2d1fa723 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 14 Apr 2021 15:28:46 +0300 Subject: [PATCH] net: socket: Workaround issue with recent GCC and fcntl macro If we have CONFIG_NET_SOCKETS_POSIX_NAMES enabled (which is now default), and also have CONFIG_NEWLIB_LIBC enabled, latest versions of GCC throw a strange error like: error: conflicting types for 'zsock_fcntl' 692 | #define fcntl zsock_fcntl After enough consideration, it seems that when Newlib is used, its fcntl.h header is used, which declares fcntl() with POSIX prototype: "int fcntl(int fd, int cmd, ...)". It seems that recent GCC, when seeing the #define like above, checks that its right-hand side (zsock_fcntl(int, int, int) above) is compatible with an existing LHS prototype. That doesn't make sense from the point of view of the C preprocessor semantics, and yet that's what apparently happens. Make GCC happy by defining an inline wrapper function with signature compatible with POSIX fcntl prototype, and use it in the define, instead of zsock_fcntl directly. Signed-off-by: Paul Sokolovsky --- include/net/socket.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/include/net/socket.h b/include/net/socket.h index 1f33b6bbfb5..f41b902ba5e 100644 --- a/include/net/socket.h +++ b/include/net/socket.h @@ -688,8 +688,22 @@ static inline ssize_t recv(int sock, void *buf, size_t max_len, int flags) return zsock_recv(sock, buf, max_len, flags); } -/* This conflicts with fcntl.h, so code must include fcntl.h before socket.h: */ -#define fcntl zsock_fcntl +/* + * Need this wrapper because newer GCC versions got too smart and "typecheck" + * even macros, so '#define fcntl zsock_fcntl' leads to error. + */ +static inline int zsock_fcntl_wrapper(int sock, int cmd, ...) +{ + va_list args; + int flags; + + va_start(args, cmd); + flags = va_arg(args, int); + va_end(args); + return zsock_fcntl(sock, cmd, flags); +} + +#define fcntl zsock_fcntl_wrapper static inline ssize_t sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr,