分类: LINUX
2011-12-25 22:09:46
++++++APUE读书笔记-02UNIX标准和实现-05一些限制++++++
5、一些限制
================================================
实现定义了许多的魔术数和常量。这些值要么被硬性编码到应用程序中,要么通过特定的技术来确定。由于我们前面所叙述的各种标准化努力工作,有越来越多的可移植方法为我们提供了确定这些魔术数以及实现定义的限制(常量),有助于增加我们软件的可移植特性。
有两种类型的限制:
(a)编译期间的限制(例如,最大的短整型值是多少?)
(b)运行期间的限制(例如,一个文件名称中包含多少个字符?)
编译期间的限制可以在头文件中定义,由应用程序在编译期间包含那个头文件。但是运行期间的限制需要进程调用一个函数来获得限制的值。
另外,有一些限制在一个给定的实现中可能是固定的,因此可以在一个头文件中静态地定义,而在另一个实现上则可能是变动的,需要调用一个运行时函数 。例如文件名的最大字符数。系统V由于历史原因只允许文件名有14个字符,而伯克利的系统则将此增加为255。SVR4允许我们对每一个创建的文件系统指明是系统 V文件系统还是BSD文件系统,而每个系统有不同的限制。这就是运行期间限制的一个实例,即文件名的最大长度依赖于文件所处的文件系统。例如,根文件系统中的文件名长度限制可能是 14个字符,而在某个其他文件系统中文件名长度限制可能是255个字符。
为了解决这些问题,提供了三种限制:
(a) 编辑期间限制(头文件) 。
(b) 不与文件或目录相关联的运行期间限制(sysconf函数)。
(c) 与文件或目录相关联的运行期间限制(pathconf和fpathconf函数集)。
更让人头痛的是,如果一个特定的运行时间限制在一个给定的系统上是固定的,那么可将其静态地定义在一个头文件中,但是,如果没有将其定义在头文件中,则应用程序就必须调用三个conf函数中的一个(我们很快就会对它们进行说明),以确定其运行时间值。
(下面大致对各种限制进行介绍,具体请参见参考资料)
(1)ISO C限制
所有由ANSI C定义的限制都是编译时间限制。
如下:
+-----------------------------------------------------------------------------------------------------------+
| Name | Description | Minimum acceptable value | Typical value |
|------------+------------------------------------+----------------------------+----------------------------|
| CHAR_BIT | bits in a char | 8 | 8 |
|------------+------------------------------------+----------------------------+----------------------------|
| CHAR_MAX | max value of char | (see later) | 127 |
|------------+------------------------------------+----------------------------+----------------------------|
| CHAR_MIN | min value of char | (see later) | 128 |
|------------+------------------------------------+----------------------------+----------------------------|
| SCHAR_MAX | max value of signed char | 127 | 127 |
|------------+------------------------------------+----------------------------+----------------------------|
| SCHAR_MIN | min value of signed char | 127 | 128 |
|------------+------------------------------------+----------------------------+----------------------------|
| UCHAR_MAX | max value of unsigned char | 255 | 255 |
|------------+------------------------------------+----------------------------+----------------------------|
| INT_MAX | max value of int | 32,767 | 2,147,483,647 |
|------------+------------------------------------+----------------------------+----------------------------|
| INT_MIN | min value of int | 32,767 | 2,147,483,648 |
|------------+------------------------------------+----------------------------+----------------------------|
| UINT_MAX | max value of unsigned int | 65,535 | 4,294,967,295 |
|------------+------------------------------------+----------------------------+----------------------------|
| SHRT_MIN | min value of short | 32,767 | 32,768 |
|------------+------------------------------------+----------------------------+----------------------------|
| SHRT_MAX | max value of short | 32,767 | 32,767 |
|------------+------------------------------------+----------------------------+----------------------------|
| USHRT_MAX | max value of unsigned short | 65,535 | 65,535 |
|------------+------------------------------------+----------------------------+----------------------------|
| LONG_MAX | max value of long | 2,147,483,647 | 2,147,483,647 |
|------------+------------------------------------+----------------------------+----------------------------|
| LONG_MIN | min value of long | 2,147,483,647 | 2,147,483,648 |
|------------+------------------------------------+----------------------------+----------------------------|
| ULONG_MAX | max value of unsigned long | 4,294,967,295 | 4,294,967,295 |
|------------+------------------------------------+----------------------------+----------------------------|
| LLONG_MAX | max value of long long | 9,223,372,036,854,775,807 | 9,223,372,036,854,775,807 |
|------------+------------------------------------+----------------------------+----------------------------|
| LLONG_MIN | min value of long long | 9,223,372,036,854,775,807 | 9,223,372,036,854,775,808 |
|------------+------------------------------------+----------------------------+----------------------------|
| ULLONG_MAX | max value of unsigned long long | 18,446,744,073,709,551,615 | 18,446,744,073,709,551,615 |
|------------+------------------------------------+----------------------------+----------------------------|
| MB_LEN_MAX | max number of bytes in a multibyte | 1 | 16 |
| | character constant | | |
+-----------------------------------------------------------------------------------------------------------+
ANSI C在
不同平台的ISO限制
+----------------------------------------------------------------------+
| Limit | FreeBSD 5.2.1 | Linux 2.4.22 | Mac OS X 10.3 | Solaris 9 |
|-----------+---------------+--------------+---------------+-----------|
| FOPEN_MAX | 20 | 16 | 20 | 20 |
|-----------+---------------+--------------+---------------+-----------|
| TMP_MAX | 308,915,776 | 238,328 | 308,915,776 | 17,576 |
+----------------------------------------------------------------------+
(2)POSIX 限制
POSIX.1定义了很多涉及操作系统实现限制的常数,其关系错综复杂。下表是
POSIX.1中
+-----------------------------------------------------------------------------------------------------------+
| Name | Description: minimum acceptable value for | Value |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_ARG_MAX | length of arguments to exec functions | 4,096 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_CHILD_MAX | number of child processes per real user ID | 25 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_HOST_NAME_MAX | maximum length of a host name as returned by gethostname | 255 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_LINK_MAX | number of links to a file | 8 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_LOGIN_NAME_MAX | maximum length of a login name | 9 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_MAX_CANON | number of bytes on a terminal's canonical input queue | 255 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_MAX_INPUT | space available on a terminal's input queue | 255 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_NAME_MAX | number of bytes in a filename, not including the terminating null | 14 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_NGROUPS_MAX | number of simultaneous supplementary group IDs per process | 8 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_OPEN_MAX | number of open files per process | 20 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_PATH_MAX | number of bytes in a pathname, including the terminating null | 256 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_PIPE_BUF | number of bytes that can be written atomically to a pipe | 512 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_RE_DUP_MAX | number of repeated occurrences of a basic regular expression permitted | 255 |
| | by the regexec and regcomp functions when using the interval notation \ | |
| | {m,n\} | |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_SSIZE_MAX | value that can be stored in ssize_t object | 32,767 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_STREAM_MAX | number of standard I/O streams a process can have open at once | 8 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_SYMLINK_MAX | number of bytes in a symbolic link | 255 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_SYMLOOP_MAX | number of symbolic links that can be traversed during pathname | 8 |
| | resolution | |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_TTY_NAME_MAX | length of a terminal device name, including the terminating null | 9 |
|-----------------------+--------------------------------------------------------------------------+--------|
| _POSIX_TZNAME_MAX | number of bytes for the name of a time zone | 6 |
+-----------------------------------------------------------------------------------------------------------+
这些值是不变的——它们并不随系统而改变。它们指定一个符合POSIX.1的实现应当提供至少这样大的值,所以它们被称为最小值的名字里面却包含MAX。另外,一个可移植的应用程序不应要求更大的值。我们将在本书的适当部分说明每一个常数的含意。
这些不变最小值中的某一些在实际应用中太小了,所以不变最小值的每一个都有一个相关的实现值,其名字是将上表中的名字删除前缀_POSIX_后构成的。这些个实现值并不能确保在
(3)XSI限制
XSI也定义了实现相关限制的常量.
XSI 中
+-----------------------------------------------------------------------------------------------------------+
| Name | Description | Minimum acceptable | Typical |
| | | value | value |
|-----------------+-------------------------------------------------------+--------------------+------------|
| NL_ARGMAX | maximum value of digit in calls to printf and scanf | 9 | 9 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| NL_LANGMAX | maximum number of bytes in LANG environment variable | 14 | 14 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| NL_MSGMAX | maximum message number | 32,767 | 32,767 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| NL_NMAX | maximum number of bytes in N-to-1 mapping characters | (none specified) | 1 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| NL_SETMAX | maximum set number | 255 | 255 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| NL_TEXTMAX | maximum number of bytes in a message string | _POSIX2_LINE_MAX | 2,048 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| NZERO | default process priority | 20 | 20 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| _XOPEN_IOV_MAX | maximum number of iovec structures that can be used | 16 | 16 |
| | with readv or writev | | |
|-----------------+-------------------------------------------------------+--------------------+------------|
| _XOPEN_NAME_MAX | number of bytes in a filename | 255 | 255 |
|-----------------+-------------------------------------------------------+--------------------+------------|
| _XOPEN_PATH_MAX | number of bytes in a pathname | 1,024 | 1,024 |
+-----------------------------------------------------------------------------------------------------------+
(4)sysconf, pathconf, and fpathconf 函数
我们给出了各种实现必须支持的最小限制,但是我们如何能够获得一个特定系统实际支持的值?我们前面说过,有些限制是编译期间可以确定的;有些必须在运行时间确定。我们也提到了有些限制在给定的系统中不会改变,另外一些由于它们和文件与目录相关,所以也可能会改变。运行期间的限制可以通过以下三个函数来获得:
#include
long sysconf(int name);
long pathconf(const char *pathname, int name);
long fpathconf(int filedes, int name);
返回:如果成功,那么三个函数返回相应的值,如果错误返回1。
sysconf的限制和名称参数
+-----------------------------------------------------------------------------------------------------------+
| Name of limit | Description | name argument |
|------------------+-----------------------------------------------------------------+----------------------|
| ARG_MAX | maximum length, in bytes, of arguments to the exec functions | _SC_ARG_MAX |
|------------------+-----------------------------------------------------------------+----------------------|
| ATEXIT_MAX | maximum number of functions that can be registered with the | _SC_ATEXIT_MAX |
| | atexit function | |
|------------------+-----------------------------------------------------------------+----------------------|
| CHILD_MAX | maximum number of processes per real user ID | _SC_CHILD_MAX |
|------------------+-----------------------------------------------------------------+----------------------|
| clock ticks/ | number of clock ticks per second | _SC_CLK_TCK |
| second | | |
|------------------+-----------------------------------------------------------------+----------------------|
| COLL_WEIGHTS_MAX | maximum number of weights that can be assigned to an entry of | _SC_COLL_WEIGHTS_MAX |
| | the LC_COLLATE order keyword in the locale definition file | |
|------------------+-----------------------------------------------------------------+----------------------|
| HOST_NAME_MAX | maximum length of a host name as returned by gethostname | _SC_HOST_NAME_MAX |
|------------------+-----------------------------------------------------------------+----------------------|
| IOV_MAX | maximum number of iovec structures that can be used with readv | _SC_IOV_MAX |
| | or writev | |
|------------------+-----------------------------------------------------------------+----------------------|
| LINE_MAX | maximum length of a utility's input line | _SC_LINE_MAX |
|------------------+-----------------------------------------------------------------+----------------------|
| LOGIN_NAME_MAX | maximum length of a login name | _SC_LOGIN_NAME_MAX |
|------------------+-----------------------------------------------------------------+----------------------|
| NGROUPS_MAX | maximum number of simultaneous supplementary process group IDs | _SC_NGROUPS_MAX |
| | per process | |
|------------------+-----------------------------------------------------------------+----------------------|
| OPEN_MAX | maximum number of open files per process | _SC_OPEN_MAX |
|------------------+-----------------------------------------------------------------+----------------------|
| PAGESIZE | system memory page size, in bytes | _SC_PAGESIZE |
|------------------+-----------------------------------------------------------------+----------------------|
| PAGE_SIZE | system memory page size, in bytes | _SC_PAGE_SIZE |
|------------------+-----------------------------------------------------------------+----------------------|
| RE_DUP_MAX | number of repeated occurrences of a basic regular expression | _SC_RE_DUP_MAX |
| | permitted by the regexec and regcomp functions when using the | |
| | interval notation \{m,n\} | |
|------------------+-----------------------------------------------------------------+----------------------|
| STREAM_MAX | maximum number of standard I/O streams per process at any given | _SC_STREAM_MAX |
| | time; if defined, it must have the same value as FOPEN_MAX | |
|------------------+-----------------------------------------------------------------+----------------------|
| SYMLOOP_MAX | number of symbolic links that can be traversed during pathname | _SC_SYMLOOP_MAX |
| | resolution | |
|------------------+-----------------------------------------------------------------+----------------------|
| TTY_NAME_MAX | length of a terminal device name, including the terminating | _SC_TTY_NAME_MAX |
| | null | |
|------------------+-----------------------------------------------------------------+----------------------|
| TZNAME_MAX | maximum number of bytes for the name of a time zone | _SC_TZNAME_MAX |
+-----------------------------------------------------------------------------------------------------------+
pathconf和fpathconf的限制和名称参数
+-----------------------------------------------------------------------------------------------------------+
| Name of | | |
| limit | Description | name argument |
|--------------+-------------------------------------------------------------------------+------------------|
| FILESIZEBITS | minimum number of bits needed to represent, as a signed integer value, | _PC_FILESIZEBITS |
| | the maximum size of a regular file allowed in the specified directory | |
|--------------+-------------------------------------------------------------------------+------------------|
| LINK_MAX | maximum value of a file's link count | _PC_LINK_MAX |
|--------------+-------------------------------------------------------------------------+------------------|
| MAX_CANON | maximum number of bytes on a terminal's canonical input queue | _PC_MAX_CANON |
|--------------+-------------------------------------------------------------------------+------------------|
| MAX_INPUT | number of bytes for which space is available on terminal's input queue | _PC_MAX_INPUT |
|--------------+-------------------------------------------------------------------------+------------------|
| NAME_MAX | maximum number of bytes in a filename (does not include a null at end) | _PC_NAME_MAX |
|--------------+-------------------------------------------------------------------------+------------------|
| PATH_MAX | maximum number of bytes in a relative pathname, including the | _PC_PATH_MAX |
| | terminating null | |
|--------------+-------------------------------------------------------------------------+------------------|
| PIPE_BUF | maximum number of bytes that can be written atomically to a pipe | _PC_PIPE_BUF |
|--------------+-------------------------------------------------------------------------+------------------|
| SYMLINK_MAX | number of bytes in a symbolic link | _PC_SYMLINK_MAX |
+-----------------------------------------------------------------------------------------------------------+
下面更详细地说明这三个函数的不同返回值。
(a)如果name不是上表中的一个合适的常数,则所有这三个函数都返回-1,并将errno设置为EINVAL。
(b)有些名称可能或者返回该变量的值(返回值≥O ),或者返回-1,这表示该值是不确定的,此时并不更改errno的值。
(c)对_SC_CLK_TCK的返回值是每秒的时钟滴答数,以用于times函数的返回值(见8章15节)。
对于pathconf的pahname参数和fpathconf的filedes参数,也有一些限制,如果不满足这些限制,将会导致结果不确定,这里不说了,具体参见参考资料。下面代码给出了一个例子:
打印所有的可能sysconf和pathconf值
#include "apue.h"
#include
#include
static void pr_sysconf(char *, int);
static void pr_pathconf(char *, char *, int);
int
main(int argc, char *argv[])
{
if (argc != 2)
err_quit("usage: a.out
#ifdef ARG_MAX
printf("ARG_MAX defined to be %d\n", ARG_MAX+0);
#else
printf("no symbol for ARG_MAX\n");
#endif
#ifdef _SC_ARG_MAX
pr_sysconf("ARG_MAX =", _SC_ARG_MAX);
#else
printf("no symbol for _SC_ARG_MAX\n");
#endif
/* similar processing for all the rest of the sysconf symbols... */
#ifdef MAX_CANON
printf("MAX_CANON defined to be %d\n", MAX_CANON+0);
#else
printf("no symbol for MAX_CANON\n");
#endif
#ifdef _PC_MAX_CANON
pr_pathconf("MAX_CANON =", argv[1], _PC_MAX_CANON);
#else
printf("no symbol for _PC_MAX_CANON\n");
#endif
/* similar processing for all the rest of the pathconf symbols... */
exit(0);
}
static void
pr_sysconf(char *mesg, int name)
{
long val;
fputs(mesg, stdout);
errno = 0;
if ((val = sysconf(name)) < 0) {
if (errno != 0) {
if (errno == EINVAL)
fputs(" (not supported)\n", stdout);
else
err_sys("sysconf error");
} else {
fputs(" (no limit)\n", stdout);
}
} else {
printf(" %ld\n", val);
}
}
static void
pr_pathconf(char *mesg, char *path, int name)
{
long val;
fputs(mesg, stdout);
errno = 0;
if ((val = pathconf(path, name)) < 0) {
if (errno != 0) {
if (errno == EINVAL)
fputs(" (not supported)\n", stdout);
else
err_sys("pathconf error, path = %s", path);
} else {
fputs(" (no limit)\n", stdout);
}
} else {
printf(" %ld\n", val);
}
}
下面是以上代码运行在本书所基于的、四个平台上面的结果:
一个配置限制的例子
+---------------------------------------------------------------------------------------------------------+
| | | | | Solaris 9 |
| Limit | FreeBSD 5.2.1 | Linux 2.4.22 | Mac OS X 10.3 |------------------------------------|
| | | | | UFS file system | PCFS file system |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| ARG_MAX | 65,536 | 131,072 | 262,144 | 1,048,320 | 1,048,320 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| ATEXIT_MAX | 32 | 2,147,483,647 | no symbol | no limit | no limit |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| CHARCLASS_NAME_MAX | no symbol | 2,048 | no symbol | 14 | 14 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| CHILD_MAX | 867 | 999 | 100 | 7,877 | 7,877 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| clock ticks/second | 128 | 100 | 100 | 100 | 100 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| COLL_WEIGHTS_MAX | 0 | 255 | 2 | 10 | 10 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| FILESIZEBITS | unsupported | 64 | no symbol | 41 | unsupported |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| HOST_NAME_MAX | 255 | unsupported | no symbol | no symbol | no symbol |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| IOV_MAX | 1,024 | no limit | no symbol | 16 | 16 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| LINE_MAX | 2,048 | 2,048 | 2,048 | 2,048 | 2,048 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| LINK_MAX | 32,767 | 32,000 | 32,767 | 32,767 | 1 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| LOGIN_NAME_MAX | 17 | 256 | no symbol | 9 | 9 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| MAX_CANON | 255 | 255 | 255 | 256 | 256 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| MAX_INPUT | 255 | 255 | 255 | 512 | 512 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| NAME_MAX | 255 | 255 | 765 | 255 | 8 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| NGROUPS_MAX | 16 | 32 | 16 | 16 | 16 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| OPEN_MAX | 1,735 | 1,024 | 256 | 256 | 256 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| PAGESIZE | 4,096 | 4,096 | 4,096 | 8,192 | 8,192 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| PAGE_SIZE | 4,096 | 4,096 | no symbol | 8,192 | 8,192 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| PATH_MAX | 1,024 | 4,096 | 1,024 | 1,024 | 1,024 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| PIPE_BUF | 512 | 4,096 | 512 | 5,120 | 5,120 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| RE_DUP_MAX | 255 | 32,767 | 255 | 255 | 255 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| STREAM_MAX | 1,735 | 16 | 20 | 256 | 256 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| SYMLINK_MAX | unsupported | no limit | no symbol | no symbol | no symbol |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| SYMLOOP_MAX | 32 | no limit | no symbol | no symbol | no symbol |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| TTY_NAME_MAX | 255 | 32 | no symbol | 128 | 128 |
|--------------------+---------------+---------------+---------------+-----------------+------------------|
| TZNAME_MAX | 255 | 6 | 255 | no limit | no limit |
+---------------------------------------------------------------------------------------------------------+
参考: