Linux C 获取系统限制
问题引入
POSIX限制和XSI限制,规定了一些系统实现必须支持的最小值,比如<limits.h>
中的POSXI.1规定_POSIX_OPEN_MAX
(每个进程打开文件数)最小值为20,_POSIX_PATH_MAX
(路径名中的字节数,包括null 终结符)最小为256,而XSI规定_XOPEN_PATH_MAX
(路径名中的字节数)最小值为1024。
然而具体统实现,支持的限制值不一定是最小值。问题来了,如何才能找到特定系统实际支持的限制值呢?
限制值分类
限制值根据运行时是否可变,分为两类,分别使用不同的办法确定实际值:
- 某些限制值编译时可用,即在给定系统中不会更改;
通常,直接用一个宏定义就能获取。
- 另一些限制值,必须在运行时确定,因为可能与文件或目录关联,运行时可改变;
POSIX 标准系统调用函数sysconf, pathconf, fpathconf
就是用来确定这类运行时可改变值。
sysconf, pathconf, fpathconf
sysconf说明
sysconf获取与系统有关配置信息,非专门的文件相关。
原型:
#include <unistd.h>
long sysconf(int name);
- name用于标识系统限制,以
_SC_
开头的常量(定义在<bits/confname.h>
,不过应该include <unistd.h>
)。
比如,_SC_OPEN_MAX
(限制名OPEN_MAX
) 表示每个进程打开的最大文件数,要求_SC_OPEN_MAX >= _POSIX_OPEN_MAX (20)
。
pathconf, fpathconf
pathconf获取与文件相关的配置值。
原型:
#include <unistd.h>
long pathconf(char *path, int name);
long fpathconf(int fd, int name);
- path 根据不同的name,有不同的要求,一般必须是一个文件或目录的路径。
- name也是用于标识系统限制,是以
_PC_
开头的常量(位置同sysconf的name参数,也是<bits/confname.h>
)。比如,_PC_PATH_MAX
(限制名PATH_MAX
)表示当path是当前工作目录时,相对路径名的最大长度,要求_PC_PATH_MAX >= _POSIX_PATH_MAX (256)
fpathconf与pathconf基本相同,区别:fpathconf的参数fd必须是一个已经open的文件描述符。
参数name及返回值
-
如果name不是一个合适的常量,比如sysconf或pathconf支持的name以外的值,那么这3个函数都返回-1,且errno置为EINVAL(参数无效错误)。
-
有些name作为参数,得到一个变量值(>=0)或提示该值不确定。不确定的值,通过返回-1,且不改变errno。
因此,程序获取运行时的限制值时,也要处理不确定值的情况,通常是得到不确定值时猜测一个值。
i.g. 获取NAME_MAX
限制值时,如果不确定就默认猜255
// 获取限制NAME_MAX
long name_max = pathconf(".", _PC_NAME_MAX);
if (name_max == -1) {
name_max = 255; // guess
}
// 申请文件名缓存
char *filename = (char *)malloc(name_max + 1); // + 1 for null byte
...
free(filename);
参考
AUPE 第3版 P33~35