[unix]sysconf、pathconf和fpathconf
2015-08-17 00:25
288 查看
在编程时,很多情况需要依据系统而定,如果系统不支持 或者未定义 需要自身去定义的话
这就称之为限制,限制分两种:
1.编译时限制 这种限制可以在头文件内定义
2.运行时限制 这种情况很大程度上由系统决定所以就需要能判断系统情况的函数来帮助我们 当遇到这种限制的时候该如何去做。
POSIX规定了各种操作系统实现必须支持的各种限制的最小值,但是怎样才能找到一个特定系统实际支持的限制呢?
POSIX决定提供三个运行时确定函数以供调用:sysconf,pathconf,fpathconf,用它们可以在运行时得到实际值。
这三个函数是用来求一些限制的,unix中有以下三种限制:
(1)编译时限制(头文件)
(2)不与文件或目录相关联的运行时限制(sysconf函数)
(3)与文件或目录相关联的运行时限制(pathconf函数和fpahtconf函数)
其中最后面的两个函数的区别是,一个使用路径名作为参数 ,另一个则取文件描述符作为参数。
使用一种技术:
如果系统确定了值(编译时和运行时),那么毫无疑问,使用系统提供的值;如果系统没提供,那么只有用臆测值,虽然这种技术并不能保证所有情况代码都能完美工作,但依然是我们可选择技术中最好多技术了.
编写一个程序使用以上方法:
输出结果:
ARG_MAX defined to be 262144.
_SC_ARG_MAX 262144.
ADVISORY_INFO defined to be -1.
no limit
前两行表明系统定义了参数的最大长度(ARC_MAX) 并且提供了默认值
后两行表明虽然系统定义了 ,但是并未给我们提供默认值 所以需要我们自己去根据实际情况实现。
实际应用--为路径名开辟空间
很多时候需要用户输入文件路径名,我们往往用一个字符数组来保存这个路径名,所以获取系统所支持最大路径名可以提高代码移植.
所以可以看出三种函数为我们处理多平台兼容性提供了很大的便利性。
这就称之为限制,限制分两种:
1.编译时限制 这种限制可以在头文件内定义
2.运行时限制 这种情况很大程度上由系统决定所以就需要能判断系统情况的函数来帮助我们 当遇到这种限制的时候该如何去做。
POSIX规定了各种操作系统实现必须支持的各种限制的最小值,但是怎样才能找到一个特定系统实际支持的限制呢?
POSIX决定提供三个运行时确定函数以供调用:sysconf,pathconf,fpathconf,用它们可以在运行时得到实际值。
<span style="font-size:14px;">#include <unistd.h> long sysconf(int name); long pathconf(const char *pathname, int name); long fpathname(int filedes, int name); 所有函数返回值:若成功则返回相应值;若出错则返回-1.</span>
这三个函数是用来求一些限制的,unix中有以下三种限制:
(1)编译时限制(头文件)
(2)不与文件或目录相关联的运行时限制(sysconf函数)
(3)与文件或目录相关联的运行时限制(pathconf函数和fpahtconf函数)
其中最后面的两个函数的区别是,一个使用路径名作为参数 ,另一个则取文件描述符作为参数。
使用一种技术:
如果系统确定了值(编译时和运行时),那么毫无疑问,使用系统提供的值;如果系统没提供,那么只有用臆测值,虽然这种技术并不能保证所有情况代码都能完美工作,但依然是我们可选择技术中最好多技术了.
编写一个程序使用以上方法:
#include<stdio.h> #include<errno.h> #include<limits.h> #include<unistd.h> int main(int argc, char *argv[]) { //test arguments lenght. #ifdef ARG_MAX printf("ARG_MAX defined to be %d.\n",ARG_MAX); #else printf("no symbol for ARG_MAX.\n"); #endif long int arg_max=0; //get the value system defined. arg_max = sysconf(_SC_ARG_MAX); //if system doesn't provide a default value if(arg_max < 0) { //if system doesn't support this attribute. if(errno != 0) { if(errno == EINVAL) printf("name not valid.\n"); else printf("sysconf error.\n"); } //support this attribute and we can do something by ourself. else { printf("no limit.\n"); } } //system has provided a default value else { printf("_SC_ARG_MAX %ld.\n",arg_max); } #ifdef _POSIX_ADVISORY_INFO printf("ADVISORY_INFO defined to be %d.\n",_POSIX_ADVISORY_INFO); #else printf("no symbol for ADVISORY_INFO.\n"); #endif long int advisory_info=0; advisory_info=sysconf(_SC_ADVISORY_INFO); if (advisory_info<0) { if (errno!=0) { if (errno==EINVAL) { printf("name not valid.\n"); }else{ printf("sysconf error.\n"); } }else { printf("no limit"); } }else { printf("_SC_ADVISORY_INFO defined to be %d.\n",_SC_ADVISORY_INFO); } return 0; }
输出结果:
ARG_MAX defined to be 262144.
_SC_ARG_MAX 262144.
ADVISORY_INFO defined to be -1.
no limit
前两行表明系统定义了参数的最大长度(ARC_MAX) 并且提供了默认值
后两行表明虽然系统定义了 ,但是并未给我们提供默认值 所以需要我们自己去根据实际情况实现。
实际应用--为路径名开辟空间
很多时候需要用户输入文件路径名,我们往往用一个字符数组来保存这个路径名,所以获取系统所支持最大路径名可以提高代码移植.
#include<errno.h> #include<limits.h> #include<unistd.h> //先判断是否在编译时提供了PATH_MAX值 #ifdef PATH_MAX static int pathmax=PATH_MAX; #else static int pathmax=0; #endif #define PATH_MAX_GUESS 256 //size!=null则用于保存开辟空间大小 char * path_alloc(int *size){ char *ptr; if(pathmax==0){ errno=0; if( (pathmax=pathconf("/",_PC_PATH_MAX)) <0){ //pathconf返回了负数,但是并没有出错,只是说明该值不确定性 if(errno==0){ pathmax=PATH_MAX_GUESS; } else{ perror("Error in pathconf ."); } } else{ //解决 根目录 “/” 开辟的空间 pathmax++; } } //因为limits中没有为字符串的null预留空间 if( (ptr=malloc(pathmax+1)) ==NULL){ perror("Error in malloc ."); } if(size!=NULL){ *size=pathmax+1; } return ptr; }
所以可以看出三种函数为我们处理多平台兼容性提供了很大的便利性。
相关文章推荐
- 矩阵连乘(3)
- PHP 扩展开发[从零开始编写第一个PHP扩展]
- HDU - 2121 Ice_cream’s world II(朱刘算法+虚根)
- [LeetCode][JavaScript]Binary Tree Paths
- HDU 3530 RMQ+twopointer/单调队列
- 逆序对问题
- 老电脑如果从windows7升级到windows10不断重启进不了系统,还是想用windows10,怎么办?
- poj3984广搜c语言
- LeetCode Divide Two Integers
- LeetCode Divide Two Integers
- 文件对象-读操作
- Xcode7 采用空白模版运行错误
- cordova配置文件config.xm
- Linux 下 eclipse 创建快捷方式
- ORA-00257:archiver error问题处理方法
- Python的替换函数——strip(),replace()和re.sub()
- codeforces 566B Replicating Processes
- jQuery AJAX
- ORA-00257:archiver error问题处理方法
- linux添加静态路由