【TLPI读书笔记】 十一、系统限制和选项
因为系统限制和选项会影响应用程序的行为,所以可移植应用程序需要获取限制值,弄清系统对选项对支持情况。C语言标准和SUSv3为此而提供了两种重要途径。
- 在编译程序时能够获得一些限制和选项
- 另外一些限制和选项在程序运行时可能会发生变化
系统限制
SUSv3要求,针对其所规范的每个限制,所有实现都必须支持一个最小值。在大多数情况下,会将这些最小值定义为<limits.h>
文件中的常量,常量命名形式如_POSIX_XXX_MAX
。在特定系统上获取限制,通常可取的方法即使用<limits.h>
文件、sysconf()
或pathconf()
。
每个限制都有一个名称,与上述最小值的名称相对应,但缺少了_POSIX_
前缀。
SUSv3将其规定的限制归为3类:运行时恒定值、路径名变量值和运行时可增加值:
- 运行时恒定值(可能不确定)
所谓运行时恒定值是指在某一限制,若已然在<limits.h>
文件中定义,则对于实现而言固定不变。然而该值可能是不确定的,因而在<limits.h>
文件中会忽略对其定义。在这种情况下,应用程序可以使用sysconf()
来获取运行时的值。 - 路径名变量值
所谓路径名变量值是指与路径名(文件、目录、终端等)相关的限制,每个限制可能是相对于某个系统实现的常量,也可能随文件系统的不同而不同。在限制可能因路径名而发生变化的情况下,应用程序可以使用pathconf()
或fpathconf()
来获取该值。 - 运行时可增加值
运行时可增加值是指某一限制,相对于特定实现其值固定,且运行此实现的所有系统至少都应支持这一最小值。然而特定系统在运行时可能会增加该值,应用程序可以使用sysconf()
来获得系统所支持的实际值。
从shell中获取限制和选项:getconf
在shell中,可以使用getconf
命令获取特定UNIX系统中已然实现的限制和选项。
在运行时获取系统限制(和选项)
sysconf()
函数允许应用程序在运行时获得系统限制值。
#include <unistd.h>
long sysconf(int name);
Returns value of limit specified by name, of -1 if limit is indeterminate or an error occurred
参数
name
:应为定义于<unistd.h>
文件中的_SC_
系列常量之一
返回值
- 成功:返回限制值
- 失败:返回
-1
,如果为发生错误还会设置errno
运行时获取与文件相关的限制(和选项)
pathconf()
和fpathconf()
函数允许应用程序在运行时获取文件相关的限制值。
#include <unistd.h>
long pathconf(const char *pathname, int name);
long fpathconf(int fd, int name);
Both return value of limit specified by name, or -1 if limit is indeterminate or an error occurred
pathconf()
和fpathconf()
之间的唯一区别在于对文件或目录的指定方式。
参数
pathname
:文件路径fd
:文件描述符name
:应为定义于<unistd.h>
文件中的_SC_
系列常量之一
返回值
- 成功:返回限制值
- 失败:返回
-1
,如果为发生错误还会设置errno
不确定的限制
有时,系统实现并未将一些系统限制定义为限制常量,并且sysconf()
或pathconf()
在返回相应限制时将其归为不确定。对此,可采用如下策略之一:
- 当编写一个可在多个UNIX实现间移植的应用程序时,可选择使用SUSv3所规定的最低限制值。
- 当某些情况下,切实可行的解决办法是省去对限制的检查,取而代之以执行相关的系统调用或库函数。
- 自行编写程序或函数,以推断或估算限制值。
- 也可以利用诸如 GNU Autoconf 之类的扩展工具,该工具能够确定各种系统特性及限制存在与否、如何处置。
系统选项
除了对各种系统资源的限制加以规范外,SUSv3还规定了UNIX实现可支持的各种选项。
通过在<unistd.h>
文件中定义相应常量,实现能够在编译时通告其对特定SUSv3选项的支持。
各个选项常量一经定义,其值必为下列之一:
- 值为
-1
,表示实现不支持该选项。 - 值为
0
,表示实现可能支持该选项。 - 值大于
0
,则表示实现支持该选项。
总结
本章主要讲解了各种系统限制和选项,并介绍了获取限制的函数。