因为系统限制和选项会影响应用程序的行为,所以可移植应用程序需要获取限制值,弄清系统对选项对支持情况。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,则表示实现支持该选项。

总结

本章主要讲解了各种系统限制和选项,并介绍了获取限制的函数。

标签: Linux, C/C++, TLPI

添加新评论