From: Roy Marples Date: Sat, 20 Apr 2024 19:06:22 +0000 (+0100) Subject: Add compat support for closefrom cribbed from libbsd X-Git-Tag: v10.0.7~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6a6c13f46d1d9d1695dfc4f7d82cee16c7f1c963;p=thirdparty%2Fdhcpcd.git Add compat support for closefrom cribbed from libbsd We had compat support in older dhcpcd but we want it faster when linux supports faster, because, you know, fast. --- diff --git a/compat/closefrom.c b/compat/closefrom.c new file mode 100644 index 00000000..7161573e --- /dev/null +++ b/compat/closefrom.c @@ -0,0 +1,77 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2004-2005, 2007, 2010, 2012-2015, 2017-2018 + * Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" + +#ifdef __linux__ +# include +# if defined(__NR_close_range) && !defined(SYS_close_range) +# define SYS_close_range __NR_close_range +# endif +#endif + +#include +#include + +#if defined(__linux__) && defined(SYS_close_range) +static inline int +sys_close_range(unsigned int fd, unsigned int max_fd, unsigned int flags) +{ + + return (int)syscall(SYS_close_range, fd, max_fd, flags); +} +#endif + +/* + * Close all file descriptors greater than or equal to lowfd. + * This is the expensive (fallback) method. + */ +static int +closefrom_fallback(int lowfd) +{ + int fd, maxfd; + +#ifdef _SC_OPEN_MAX + maxfd = (int)sysconf(_SC_OPEN_MAX); +#else + maxfd = getdtablesize(); +#endif + if (maxfd == -1) + return -1; + + for (fd = lowfd; fd < maxfd; fd++) + close(fd); + return 0; +} + +/* + * * Close all file descriptors greater than or equal to lowfd. + * * We try the fast way first, falling back on the slow method. + * */ +void +closefrom(int lowfd) +{ + +#if defined(__linux__) && defined(SYS_close_range) + if (sys_close_range((unsigned int)lowfd, UINT_MAX, 0) == 0) + return; +#endif + + closefrom_fallback(lowfd); +} diff --git a/compat/closefrom.h b/compat/closefrom.h new file mode 100644 index 00000000..70ce71f6 --- /dev/null +++ b/compat/closefrom.h @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2004-2005, 2007, 2010, 2012-2015, 2017-2018 + * Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef CLOSEFROM_H +#define CLOSEFROM_H + +void closefrom(int); + +#endif diff --git a/configure b/configure index 5237b0e2..8bc65184 100755 --- a/configure +++ b/configure @@ -811,6 +811,27 @@ fi rm -f _clock_gettime.c _clock_gettime $abort && exit 1 +if [ -z "$CLOSEFROM" ]; then + printf "Testing for closefrom ... " + cat <_closefrom.c +#include +int main(void) { + return closefrom(3); +} +EOF + if $XCC _closefrom.c -o _closefrom 2>&3; then + CLOSEFROM=yes + else + CLOSEFROM=no + fi + echo "$CLOSEFROM" +fi +rm -f _closefrom.c _closefrom +if [ "$CLOSEFROM" = no ]; then + echo "COMPAT_SRCS+= compat/closefrom.c" >>$CONFIG_MK + echo "#include \"compat/closefrom.h\"" >>$CONFIG_H +fi + printf "Testing ioctl request type ... " cat <_ioctl.c #include