[PATCH v7 2/4] linux: Add close_range

Florian Weimer fweimer@redhat.com
Wed Jul 7 10:22:39 GMT 2021


* Adhemerval Zanella via Libc-alpha:


> diff --git a/manual/llio.texi b/manual/llio.texi
> index eafc27120d..ea6d34dd5a 100644
> --- a/manual/llio.texi
> +++ b/manual/llio.texi
> @@ -284,6 +284,55 @@ of trying to close its underlying file descriptor with @code{close}.
>  This flushes any buffered output and updates the stream object to
>  indicate that it is closed.
>  
> +@deftypefun int close_range (unsigned int @var{lowfd}, unsigned int @var{maxfd}, int @var{flags})
> +@standards{Linux, unistd.h}
> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
> +@c This is a syscall for Linux v5.9.  There is no fallback emulation for
> +@c older kernels.
> +
> +The function @code{close_range} closes the file descriptor from @var{lowfd}
> +to @var{maxfd} (inclusive).  This function is similar to call @code{close} in
> +specified file descriptor range depending on the @var{flags}.
> +
> +This is function is only supported on recent Linux versions and @theglibc{}
> +does not provide any fallback (the application will need to handle possible
> +@code{ENOSYS}).
> +
> +The @var{flags} add options on how the files are closes.  Linux currently
> +supports:
> +
> +@vtable @code
> +@item CLOSE_RANGE_UNSHARE
> +Unshare the file descriptor table before closing file descriptors.
> +
> +@item CLOSE_RANGE_CLOEXEC
> +Set the @code{FD_CLOEXEC} bit instead of closing the file descriptor.
> +@end vtable
> +
> +The normal return value from @code{close_range} is @math{0}; a value
> +of @math{-1} is returned in case of failure.  The following @code{errno} error
> +conditions are defined for this function:
> +
> +@table @code
> +@item EINVAL
> +The @var{lowfd} value is larger than @var{maxfd} or an unsupported @var{flags}
> +is used.
> +
> +@item ENOMEM
> +Either there is not enough memory for the operation, or the process is
> +out of address space.

I think the address space limitation does not apply here, and this error
can only happen for CLOSE_RANGE_UNSHARE.  This is important information
because plain close cannot fail, either.  No possibility of failure is a
requirement in many cases to use this interface.

> +@item EMFILE
> +The process has too many files open.
> +The maximum number of file descriptors is controlled by the
> +@code{RLIMIT_NOFILE} resource limit; @pxref{Limits on Resources}.

Can EMFILE (or ENFILE) really happen even with CLOSE_RANGE_UNSHARE?  I
don't think so.

> diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> index 2e529be577..bf313e8af8 100644
> --- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> +++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> @@ -33,4 +33,26 @@
>     not detached and has not been joined.  */
>  extern __pid_t gettid (void) __THROW;
>  
> +#ifdef __has_include
> +# if __has_include ("linux/close_range.h")
> +#  include "linux/close_range.h"
> +# endif
>  #endif
> +/* Unshare the file descriptor table before closing file descriptors.  */
> +#ifndef CLOSE_RANGE_UNSHARE
> +# define CLOSE_RANGE_UNSHARE (1U << 1)
> +#endif
> +/* Set the FD_CLOEXEC bit instead of closing the file descriptor.  */
> +#ifndef CLOSE_RANGE_CLOEXEC
> +# define CLOSE_RANGE_CLOEXEC (1U << 2)
> +#endif
> +
> +/* Close all file descriptors in the range FD up to MAX_FD.  The flag FLAGS
> +   are define by the CLOSE_RANGE prefix.  This function behaves like close
> +   on the range, but in a fail-safe where it will either fail and not close
> +   any file descriptor or close all of them.  Returns 0 on successor or -1
> +   for failure (and sets errno accordingly).  */
> +extern int close_range (unsigned int __fd, unsigned int __max_fd,
> +			int __flags) __THROW;

The fail-safe aspect is not mentioned in the manual.  It's confused
because it's unclear what happens with gaps.

Thanks,
Florian



More information about the Libc-alpha mailing list