获取最高分配的文件描述符 [英] Getting the highest allocated file descriptor

查看:243
本文介绍了获取最高分配的文件描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在可移植的方式(POSIX),以获取当前进程的最高分配文件描述符号?

Is there a portable way (POSIX) to get the highest allocated file descriptor number for the current process?

例如,我知道在AIX上有一种获取号码的好方法,但是我正在寻找一种可移植的方法.

I know that there's a nice way to get the number on AIX, for example, but I'm looking for a portable method.

我要问的原因是我想关闭所有打开的文件描述符.我的程序是一台服务器,该服务器以root用户身份运行,并且为非root用户执行并执行子程序.在子进程中保留特权文件描述符处于打开状态是一个安全问题.某些文件描述符可能由我无法控制的代码(C库,第三方库等)打开,所以我也不能依赖FD_CLOEXEC.

The reason I'm asking is that I want to close all open file descriptors. My program is a server which runs as root and forks and execs child programs for non-root users. Leaving the privileged file descriptors open in the child process is a security problem. Some file descriptors may be opened by code I cannot control (the C library, third party libraries, etc.), so I cannot rely on FD_CLOEXEC either.

推荐答案

虽然可移植,但是关闭所有文件描述符直到sysconf(_SC_OPEN_MAX)都不可靠,因为在大多数系统上,此调用返回当前文件描述符的软限制,这可能被降低到最高使用文件描述符以下.另一个问题是,在许多系统上,sysconf(_SC_OPEN_MAX)可能返回INT_MAX,这可能会导致这种方法的运行速度慢得令人无法接受.不幸的是,没有可靠,可移植的替代方案,该替代方案不涉及遍历每个可能的非负int文件描述符.

While portable, closing all file descriptors up to sysconf(_SC_OPEN_MAX) is not reliable, because on most systems this call returns the current file descriptor soft limit, which could have been lowered below the highest used file descriptor. Another issue is that on many systems sysconf(_SC_OPEN_MAX) may return INT_MAX, which can cause this approach to be unacceptably slow. Unfortunately, there is no reliable, portable alternative that does not involve iterating over every possible non-negative int file descriptor.

尽管不是便携式的,但当今大多数常用的操作系统都提供了以下一种或多种解决此问题的方法:

Although not portable, most operating systems in common use today provide one or more of the following solutions to this problem:

  1. 用于关闭所有文件描述符> = fd 的库函数.对于关闭所有文件描述符的常见情况,这是最简单的解决方案,尽管它不能用于其他用途.要关闭除特定集合以外的所有文件描述符,可以使用dup2事先将它们移动到低端,然后在必要时将它们随后移回

  1. A library function to close all file descriptors >= fd. This is the simplest solution for the common case of closing all file descriptors, although it cannot be used for much else. To close all file descriptors except for a certain set, dup2 can be used to move them to the low end beforehand, and to move them back afterward if necessary.

  • closefrom(fd)(Solaris 9或更高版本,FreeBSD 7.3或8.0和更高版本,NetBSD 3.0或更高版本,OpenBSD 3.5或更高版本.)

  • closefrom(fd) (Solaris 9 or later, FreeBSD 7.3 or 8.0 and later, NetBSD 3.0 or later, OpenBSD 3.5 or later.)

fcntl(fd, F_CLOSEM, 0)(AIX,IRIX,NetBSD)

fcntl(fd, F_CLOSEM, 0) (AIX, IRIX, NetBSD)

一个库函数,用于提供该进程当前正在使用的最大文件描述符.要关闭超过一定数量的所有文件描述符,请关闭所有文件描述符直至达到最大值,或者连续获取并关闭循环中的最高文件描述符,直到达到下限为止.哪种效率更高取决于文件描述符的密度.

A library function to provide the maximum file descriptor currently in use by the process. To close all file descriptors above a certain number, either close all of them up to this maximum, or continually get and close the highest file descriptor in a loop until the low bound is reached. Which is more efficient depends on the file descriptor density.

  • fcntl(0, F_MAXFD)(NetBSD)

pstat_getproc(&ps, sizeof(struct pst_status), (size_t)0, (int)getpid())
返回有关进程的信息,包括当前在ps.pst_highestfd中打开的最高文件描述符. (HP-UX)

pstat_getproc(&ps, sizeof(struct pst_status), (size_t)0, (int)getpid())
Returns information about the process, including the highest file descriptor currently open in ps.pst_highestfd. (HP-UX)

用于列出该进程当前正在使用的所有文件描述符的库函数.这种方法更加灵活,因为它允许关闭所有文件描述符,查找最高的文件描述符,或者对每个打开的文件描述符执行几乎所有其他操作,甚至可能处理其他进程的文件. 示例(OpenSSH)

A library function to list all file descriptors currently in use by the process. This is more flexible in that it allows for closing all file descriptors, finding the highest file descriptor, or doing just about anything else on every open file descriptor, possibly even those of another process. Example (OpenSSH)

  • proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, fdinfo_buf, sz)(macOS)
  • proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, fdinfo_buf, sz) (macOS)

一个目录,其中包含每个打开的文件描述符的条目.除了不是库函数以外,其他与上述类似.这可能比其他常用方法更为复杂,并且可能由于各种原因而失败,例如未安装proc/fdescfs,chroot环境或没有可用于打开目录的文件描述符(进程或系统限制).因此,这种方法的使用通常与后备机制结合使用. 示例(OpenSSH)另一个示例( glib).

A directory containing an entry for each open file descriptor. This is similar to the above except that it isn't a library function. This can be more complicated than the other approaches for the common uses, and can fail for a variety of reasons such as proc/fdescfs not mounted, a chroot environment, or no file descriptors available to open the directory (process or system limit). Therefore use of this approach is often combined with a fallback mechanism. Example (OpenSSH), another example (glib).

  • /proc/ pid /fd//proc/self/fd/(Linux,Solaris,AIX,Cygwin,NetBSD)
    (AIX不支持"self")

  • /proc/pid/fd/ or /proc/self/fd/ (Linux, Solaris, AIX, Cygwin, NetBSD)
    (AIX does not support "self")

/dev/fd/(FreeBSD,macOS)

/dev/fd/ (FreeBSD, macOS)

使用这种方法可能难以可靠地处理所有极端情况.例如,考虑以下情况:所有文件描述符> = fd 将被关闭,而所有文件描述符<使用 fd ,当前进程资源限制为 fd ,并且使用文件描述符> = fd .由于已达到进程资源限制,因此无法打开目录.如果通过资源限制关闭 fd 中的每个文件描述符或使用sysconf(_SC_OPEN_MAX)作为后备,则不会关闭任何文件.

It can be difficult to handle all corner cases reliably with this approach. For example consider the situation where all file descriptors >= fd are to be closed, but all file descriptors < fd are used, the current process resource limit is fd, and there are file descriptors >= fd in use. Because the process resource limit has been reached the directory cannot be opened. If closing every file descriptor from fd through the resource limit or sysconf(_SC_OPEN_MAX) is used as a fallback, nothing will be closed.

这篇关于获取最高分配的文件描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆