Linux C 3获取个系统的限制系统调用 sysconf, pathconf, fpathconf

问题引入

POSIX限制和XSI限制,规定了一些系统实现必须支持的最小值,比如<limits.h>中的POSXI.1规定_POSIX_OPEN_MAX(每个进程打开文件数)最小值为20,_POSIX_PATH_MAX(路径名中的字节数,包括null 终结符)最小为256,而XSI规定_XOPEN_PATH_MAX(路径名中的字节数)最小值为1024。然而具体的系统实现,其支持的限制值不一定就是最小值。那么问题来了,如何才能找到一个特定系统实际支持的限制值呢?

限制值分类

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

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

通常,直接用一个宏定义就开得到其值。

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

sysconf, pathconf, fpathconf就是用来确定这类运行时可改变值。

sysconf, pathconf, fpathconf

#include <unistd.h>

long sysconf(int name);

#include <unistd.h>

long fpathconf(int fd, int name);
long pathconf(char *path, int name);

sysconf说明

sysconf获取与系统有关配置信息,非专门的文件相关。其参数name用于标识系统限制,是以_SC_开头的常量(定义在<bits/confname.h>,不过应该include <unistd.h>)。
比如,_SC_OPEN_MAX (限制名OPEN_MAX) 表示每个进程打开的最大文件数,要求 _SC_OPEN_MAX >= _POSIX_OPEN_MAX (20)。

pathconf, fpathconf

pathconf获取与文件相关的配置值。其参数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版 page33~35

原文地址:https://www.cnblogs.com/fortunely/p/15179795.html