Linux C 获取系统限制

问题引入

POSIX限制和XSI限制,规定了一些系统实现必须支持的最小值,比如<limits.h>中的POSXI.1规定_POSIX_OPEN_MAX(每个进程打开文件数)最小值为20,_POSIX_PATH_MAX(路径名中的字节数,包括null 终结符)最小为256,而XSI规定_XOPEN_PATH_MAX(路径名中的字节数)最小值为1024。

然而具体统实现,支持的限制值不一定是最小值。问题来了,如何才能找到特定系统实际支持的限制值呢?

限制值分类

限制值根据运行时是否可变,分为两类,分别使用不同的办法确定实际值:

  1. 某些限制值编译时可用,即在给定系统中不会更改;

通常,直接用一个宏定义就能获取。

  1. 另一些限制值,必须在运行时确定,因为可能与文件或目录关联,运行时可改变;

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及返回值

  1. 如果name不是一个合适的常量,比如sysconf或pathconf支持的name以外的值,那么这3个函数都返回-1,且errno置为EINVAL(参数无效错误)。

  2. 有些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

posted @ 2021-08-24 12:26  明明1109  阅读(364)  评论(0)    收藏  举报