From 2393e82a62e19e29e61ef3253e227c19ae7222eb Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sun, 14 Jan 2024 16:54:17 +0100 Subject: [PATCH] Cygwin: introduce close_range This function closes or sets the close-on-exec flag for a specified range of file descriptors. It is available on FreeBSD and Linux. Signed-off-by: Christian Franke --- newlib/libc/include/sys/unistd.h | 6 ++++ winsup/cygwin/cygwin.din | 1 + winsup/cygwin/include/cygwin/version.h | 3 +- winsup/cygwin/release/3.5.0 | 2 ++ winsup/cygwin/syscalls.cc | 42 ++++++++++++++++++++++++++ winsup/doc/new-features.xml | 4 +++ 6 files changed, 57 insertions(+), 1 deletion(-) diff --git a/newlib/libc/include/sys/unistd.h b/newlib/libc/include/sys/unistd.h index 25532251c..f5f1963c8 100644 --- a/newlib/libc/include/sys/unistd.h +++ b/newlib/libc/include/sys/unistd.h @@ -26,6 +26,12 @@ int chown (const char *__path, uid_t __owner, gid_t __group); int chroot (const char *__path); #endif int close (int __fildes); +#if defined(__CYGWIN__) && (__BSD_VISIBLE || __GNU_VISIBLE) +/* Available on FreeBSD (__BSD_VISIBLE) and Linux (__GNU_VISIBLE). */ +int close_range (unsigned int __firstfd, unsigned int __lastfd, int __flags); +/* CLOSE_RANGE_UNSHARE 0x01 */ /* Linux only, not yet supported. */ +#define CLOSE_RANGE_CLOEXEC 0x02 +#endif #if __POSIX_VISIBLE >= 199209 size_t confstr (int __name, char *__buf, size_t __len); #endif diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 9b76ce67a..9e354acc6 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -347,6 +347,7 @@ clog10l NOSIGFE clogf NOSIGFE clogl NOSIGFE close SIGFE +close_range SIGFE closedir SIGFE closelog SIGFE cnd_broadcast SIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index c8177c2b1..3036878c4 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -484,12 +484,13 @@ details. */ 347: Add c16rtomb, c32rtomb, mbrtoc16, mbrtoc32. 348: Add c8rtomb, mbrtoc. 349: Add fallocate. + 350: Add close_range. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 349 +#define CYGWIN_VERSION_API_MINOR 350 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/release/3.5.0 b/winsup/cygwin/release/3.5.0 index d0a6c2fc8..6209064a6 100644 --- a/winsup/cygwin/release/3.5.0 +++ b/winsup/cygwin/release/3.5.0 @@ -43,6 +43,8 @@ What's new: - New API calls: c8rtomb, c16rtomb, c32rtomb, mbrtoc8, mbrtoc16, mbrtoc32. +- New API call: close_range (available on FreeBSD and Linux). + - New API call: fallocate (Linux-specific). - Implement OSS-based sound mixer device (/dev/mixer). diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 486db1db6..aba864475 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -85,6 +85,48 @@ close_all_files (bool norelease) cygheap->fdtab.unlock (); } +/* Close or set the close-on-exec flag for all open file descriptors + from firstfd to lastfd. + Available on FreeBSD since 13 and Linux since 5.9 */ +extern "C" int +close_range (unsigned int firstfd, unsigned int lastfd, int flags) +{ + pthread_testcancel (); + + if (!(firstfd <= lastfd && (!flags || flags == CLOSE_RANGE_CLOEXEC))) + { + set_errno (EINVAL); + return -1; + } + + cygheap->fdtab.lock (); + + int size = (int) (lastfd < cygheap->fdtab.size ? lastfd + 1 : + cygheap->fdtab.size); + + for (int i = (int) firstfd; i < size; i++) + { + cygheap_fdget cfd (i, false, false); + if (cfd < 0) + continue; + + if (!flags) + { + syscall_printf ("closing fd %d", i); + cfd->close_with_arch (); + cfd.release (); + } + else /* CLOSE_RANGE_CLOEXEC */ + { + syscall_printf ("set FD_CLOEXEC on fd %d", i); + cfd->fcntl (F_SETFD, FD_CLOEXEC); + } + } + + cygheap->fdtab.unlock (); + return 0; +} + extern "C" int dup (int fd) { diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 6ae420031..0abe1c41c 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -74,6 +74,10 @@ posix_spawn_file_actions_addfchdir_np. New API calls: c8rtomb, c16rtomb, c32rtomb, mbrtoc8, mbrtoc16, mbrtoc32. + +New API call: close_range (available on FreeBSD and Linux). + + New API call: fallocate (Linux-specific). -- 2.42.1