unix限制

UNIX系统实现定义了很多幻数和常量,其中有很多已被硬编码到程序中,或用特定的技术确定。由于大量标准化工作的努力,已有若干种可移植的方法用以确定这些幻数和具体实现定义的限制。这非常有助于改善UNIX环境下软件的可移植性。
以下两种类型的限制是必需的:
1、编译时限制(例如,短整型的最大值是什么?)
2、运行时限制(例如,文件名有多少个字符?)
编译时限制可在头文件中定义,程序在编译时可以包含这些头文件。但是,运行时限制则要求进程调用一个函数获得限制值。
另外,某些限制在一个给定的实现中可能是固定的(因此可以静态地定义在一个头文件中),而在另一个实现中则可能是变动的(需要有一个运行时函数调用)。这种类型限制的一个例子是文件名的最大字符数。为了解决这类问题,提供了以下3种限制:
1、编译时限制(头文件)。
2、与文件或目录无关的运行时限制(sysconf 函数)。
3、与文件或目录有关的运行时限制(pathconf 和 fpathconf 函数)。
如果一个特定的运行时限制在一个给定的系统中并不改变,则可将其静态地定义在一个头文件中。但是,如果没有将其定义在头文件中,应用程序就必须调用3个conf函数中的一个,以确定其运行时限制。
要如何才能找到一个特定系统实际支持的限制值呢?运行时限制可调用下面三个函数之一获得:

#include <unistd.h>

long sysconf(int name);
long pathconf(const char *pathname, int name); // 用路径名作为参数
long fpathconf(int fd, int name); // 用文件描述符作为参数
/* 所有函数返回值:若成功,返回相应值;若出错,返回 -1 */

sysconf函数的name参数用来标识系统限制,以 _SC_ 开始的常量用作标识运行时限制的syscon参数。下表是sysconf函数所使用的name参数:
[table]
|限制名|说明|name参数|
|ARG_MAX|exec函数的参数最大长度(字节)|_SC_ARG_MAX|
|ATEXIT_MAX|可用atexit函数登记的最大函数个数|_SC_ATEXIT_MAX|
|CHILD_MAX|每个实际用户ID的最大进程数|_SC_CHILD_MAX|
|时钟滴答/秒|每秒时钟滴答数|_SC_CLK_TCK|
|COLL_WEIGHTS_MAX|本地定义文件中可赋予LC_COLLATE顺序关键字项的最大权重数|_SC_COLL_WEIGHTS_MAX|
|DELAYTIMER_MAX|定时器最大超限运行次数|_SC_DELAYTIMER_MAX|
|HOST_NAME_MAX|gethostname函数返回的主机名最大长度|_SC_HOST_NAME_MAX|
|IOV_MAX|readv或writev函数可使用的最多iovec结构的个数|_SC_IOV_MAX|
|LINE_MAX|实用程序输入行的最大长度|_SC_LINE_MAX|
|LOGIN_NAME_MAX|登录名的最大长度|_SC_LOGIN_NAME_MAX|
|NGROUPS_MAX|每个进程同时添加的最大进程组ID数|_SC_NGROUPS_MAX|
|OPEN_MAX|每个进程最大打开文件数|_SC_OPEN_MAX|
|PAGESIZE|系统存储页长度(字节)|_SC_PAGESIZE|
|PAGE_SIZE|系统存储页长度(字节)|_SC_PAGE_SIZE|
|RE_DUP_MAX|使用间隔表示法\{m,n\}时,函数regexec和regcomp允许的基本正则表达式重复发生次数|_SC_RE_DUP_MAX|
|RTSIG_MAX|为应用程序预留的实时信号的最大个数|_SC_RTSIG_MAX|
|SEM_NSEMS_MAX|一个进程可使用的信号量最大个数|_SC_SEM_NSEMS_MAX|
|SEM_VALUE_MAX|信号量的最大值|_SC_SEM_VALUE_MAX|
|SIGQUEUE_MAX|一个进程可排队信号的最大个数|_SC_SIGQUEUE_MAX|
|STREAM_MAX|一个_SC_STREAM_MAX进程在任意给定时刻标准I/O流的最大个数。如果定义,必须与FOPEN_MAX有相同值|_SC_STREAM_MAX|
|SYMLOOP_MAX|在解析路径名时,可遍历的符号链接数|_SC_SYMLOOP_MAX|
|TIMER_MAX|每个进程的最大定时器个数|_SC_TIMER_MAX|
|TTY_NAME_MAX|终端设备名长度,包括终止null字节|_SC_TTY_NAME_MAX|
|TZNAME_MAX|时区名中的最大字节数|_SC_TZNAME_MAX|
[/table]
pathconf和fpathconf函数为标识系统限制所使用的name参数如下表:
[table]
|限制名|说明|name参数|
|FILESISEBITS|以带符号整型值表示在指定目录中允许的普通文件最大长度所需的最小位数|_PC_FILESISEBITS|
|LINK_MAX|文件链接计数的最大值|_PC_LINE_MAX|
|MAX_CANON|终端规范输入队列的最大字节数|_PC_MAX_CANON|
|MAX_INPUT|终端输入队列可用空间的字节数|_PC_MAX_INPUT|
|NAME_MAX|文件名的最大字节数(不包括终止null字节)|_PC_NAME_MAX|
|PATH_MAX|相对路径名的最大字节数,包括终止null字节|_PC_PATH_MAX|
|PIPE_BUF|能原子地写到管道的最大字节数|_PC_PIPE_BUF|
|_POSIX_TIMESTAMP_RESOLUTION|文件时间戳的纳秒精度|_PC_TIMESTAMP_RESOLUTION|
|SYMLINK_MAX|符号链接的字节数|_PC_SYMLINK_MAX|
[/table]
现在再来详细地讨论一下这3个函数不同的返回值。
1、若name参数不是一个合适的常量,这3个函数都返回-1,并把errno置为EINVAL。
2、有些name会返回一个变量值(>=0)或者提示该值是不确定的。不确定的值通过返回-1来体现,而不改变errno的值。
3、_SC_CLK_TCK的返回值是每秒的时钟滴答数,用于times函数的返回值。
对于pathconf的参数pathname和fpathconf的参数fd有很多限制。如果不满足以下其中任何一个限制,则结果是未定义的:
1、_PC_MAX_CANON和_PC_MAX_INPUT引用的文件必须是终端文件。
2、_PC_LINK_MAX和_PC_TIMESTAMP_RESOLUTION引用的文件可以是文件或目录。如果是目录,则返回值用于目录本身,而不用于目录内的文件名项。
3、_PC_FILESIZEBITS和_PC_NAME_MAX引用的文件必须是目录,返回值用于该目录中的文件名。
4、_PC_PATH_MAX引用的文件必须是目录。但所指定的目录是工作目录时,返回值是相当路径名的最大长度。
5、_PC_PIPE_BUF引用的文件必须是管道、FIFO或目录。在管道或FIFO情况下,返回值是对所引用的管道或FIFO的限制值。对于目录,返回值是对在该目录中创建的任一FIFO的限制值。
6、_PC_SYMLINK_MAX引用的文件必须是目录。返回值是该目录中符号链接可包含字符串的最大长度。
下面这个程序可用来打印这些限制:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>

static void pr_sysconf(char *, int);
static void pr_pathconf(char *, char *, int);

int main(int argc, char **argv){
if(argc != 2){
printf("usage: %s <dirname>", argv[0]);
exit(0);
}

#ifdef ARG_MAX
printf("ARG_MAX defined to be %ld\n", (long)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_CNAON defined to be %ld\n", (long)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
printf("sysconf error\n");
}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
printf("pathconf error, path = %s\n", path);
}else{
fputs(" (no limit)\n", stdout);
}
}else{
printf(" %ld\n", val);
}
}


参考书籍:《UNIX环境高级编程》第二章:UNIX标准及实现。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux 和 Unix 的主要区别在于它们的类型和发展历史。Unix 是一种原始的操作系统,它由 AT&T 的 Bell Labs 研发,并在 1970 年首次发布。相比之下,Linux 是一种免费、开源的操作系统,它是在 Unix 的基础上发展而来的。这两种操作系统都具有类似的命令行界面和文件系统,但 Linux 更为灵活和可定制。 ### 回答2: Linux和Unix都是操作系统,但在一些方面有一些不同之处。 首先,Linux是一个开源的操作系统,而Unix通常是商业操作系统。由于Linux是开源的,因此可以自由地修改和分发,这使得它成为许多个人和组织喜欢的选择。而Unix系统则通常需要购买并获取授权。 其次,Linux是以Unix为基础进行开发的。因此,它们之间有许多相似之处。例如,它们都使用类似的命令行界面,并具有类似的文件系统和文件权限机制。这使得Unix用户能够相对轻松地切换到Linux系统并进行使用和管理。 此外,Linux和Unix在一些技术上也有一些区别。例如,在内核设计上,Linux采用了单内核的架构,而Unix采用了类似的微内核或宏内核的架构。从发展历史上看,Linux内核是在1991年由Linus Torvalds创建的,而Unix则源自20世纪70年代。 最后,虽然Linux和Unix具有一些不同之处,但它们在许多方面仍然非常相似。它们都被广泛应用于服务器环境中,具有稳定性高、安全性强和可定制性高的特点。无论是开发者还是普通用户,都可以根据自己的需求选择适合自己的操作系统。 ### 回答3: Linux和UNIX是两个不同的操作系统,让我们来看看它们之间的区别。 首先,Linux是一个开源操作系统,而UNIX是一个商业操作系统。这意味着Linux的源代码是公开的,任何人都可以查看、修改和分发它,而UNIX的源代码是受商业许可限制的,需要支付使用费用。 其次,Linux是根据UNIX的设计思想开发而来的,它保留了UNIX的一些特性,比如多用户、多任务和内核安全性。然而,Linux也有自己的独特特性,比如广泛的硬件支持、强大的网络功能和丰富的软件库。 此外,Linux和UNIX的文件系统也有所不同。UNIX使用一种称为UFS的文件系统,它具有较低的文件系统支持和性能。而Linux使用一种称为Ext(Extended File System)的文件系统,它提供了更高的性能和更丰富的功能。 另一个区别是命令行界面。UNIX使用一种称为Shell的命令行界面,而Linux在这方面更加灵活和丰富,支持多种不同的Shell,比如Bash、Zsh和Fish等。 最后,Linux有许多不同的发行版,比如Ubuntu、Debian、Red Hat和Fedora等,而UNIX则主要由大型服务器厂商提供,比如IBM、HP和Oracle等。 总的来说,Linux和UNIX是相似但不完全相同的操作系统。Linux是一个开源免费的操作系统,比较适合个人用户和小型组织,而UNIX则更适合大型企业和专业用户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值