From 6501b68ffba7f4414b3818fcc3ee945e70918772 Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Fri, 13 Jun 2025 03:04:21 +0900 Subject: [PATCH] libcasper: Use __VA_ARGS__ for function-like macros cap_net.h uses "#define cap_f(chan, a) f(a)" to call the conventional service function with the first argument of cap_f() dropped for compatibility with the environment where the casper service is unavailable. However, this function-like macro does not work when the arguments contains C99 compound literals, such as f(chan, (int[]){1,2,3}). The following is a typical example: error = cap_getaddrinfo(capnet, "192.168.0.1", "100", &(struct addrinfo){ .ai_family = AF_INET, .ai_flags = AI_NUMERICHOST }, &res); Using cap_f(chan, ...) and __VA_ARGS__ in C99 seems a reasonable solution for this problem. While there is a workaround using parenthesis around the compound literal like f(chan, ((int[]){1,2,3})), it is not intuitive and the above example works when the cap_net is available and f() is defined as a function. A possible moot point is that __VA_ARGS__ cannot control how many arguments are passed at the macro level, and "chan" is not protected. However, "chan" is less likely to be written in compound literal, and the function prototype should check the remaining arguments. Reviewed by: oshogbo Differential Revision: https://reviews.freebsd.org/D45858 --- lib/libcasper/services/cap_net/cap_net.h | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/libcasper/services/cap_net/cap_net.h b/lib/libcasper/services/cap_net/cap_net.h index 1e9a6021d24..75f93695419 100644 --- a/lib/libcasper/services/cap_net/cap_net.h +++ b/lib/libcasper/services/cap_net/cap_net.h @@ -93,18 +93,14 @@ struct hostent *cap_gethostbyaddr(cap_channel_t *chan, const void *addr, socklen_t len, int af); #else /* Capability functions. */ -#define cap_bind(chan, s, addr, addrlen) \ - bind(s, addr, addrlen) -#define cap_connect(chan, s, name, namelen) \ - connect(s, name, namelen) -#define cap_getaddrinfo(chan, hostname, servname, hints, res) \ - getaddrinfo(hostname, servname, hints, res) -#define cap_getnameinfo(chan, sa, salen, host, hostlen, serv, servlen, flags) \ - getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) +#define cap_bind(chan, ...) bind(__VA_ARGS__) +#define cap_connect(chan, ...) connect(__VA_ARGS__) +#define cap_getaddrinfo(chan, ...) getaddrinfo(__VA_ARGS__) +#define cap_getnameinfo(chan, ...) getnameinfo(__VA_ARGS__) /* Limit functions. */ -#define cap_net_limit_init(chan, mode) ((cap_net_limit_t *)malloc(8)) -#define cap_net_free(limit) free(limit) +#define cap_net_limit_init(chan, ...) ((cap_net_limit_t *)malloc(8)) +#define cap_net_free(...) free(__VA_ARGS__) static inline int cap_net_limit(cap_net_limit_t *limit) { @@ -155,9 +151,9 @@ cap_net_limit_bind(cap_net_limit_t *limit, } /* Deprecated functions. */ -#define cap_gethostbyname(chan, name) gethostbyname(name) -#define cap_gethostbyname2(chan, name, type) gethostbyname2(name, type) -#define cap_gethostbyaddr(chan, addr, len, type) gethostbyaddr(addr, len, type) +#define cap_gethostbyname(chan, ...) gethostbyname(__VA_ARGS__) +#define cap_gethostbyname2(chan, ...) gethostbyname2(__VA_ARGS__) +#define cap_gethostbyaddr(chan, ...) gethostbyaddr(__VA_ARGS__) #endif #endif /* !_CAP_NETWORK_H_ */