码迷,mamicode.com
首页 > 其他好文 > 详细

APUE学习笔记:第二章 UNIX标准化及实现

时间:2014-07-16 22:48:46      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   使用   os   

2.2UNIX标准化

2.2.1 ISO C

国际标准化组织(International Organization for Standardization,ISO)

国际电子技术委员会(International Electrotechnical Commission,IEC)

ISO C标准的意图是提供C程序的可移植性,使其能适合于大量不同的操作系统,而不只是UNIX系统。此标准不仅定义了C程序设计语言的语法和语义,还定义了其标准库。因为所有现今的UNIX系统都提供C标准中定义的库例程,所以该标准库是很重要的

按照该标准定义的各个头文件,可将ISO C库分成24个区。

ISO C标准定义的头文件:

<asser.h>:验证程序断言  <complex.h>:支持复数算术运算  <ctype.h>:字符类型  <errno.h>:出错码  <fenv.h>:浮点环境  <float.h>:浮点常量

<inttypes.h>:整型格式转换  <iso646.h>:替代关系操作符宏  <limits.h>:实现常量  <locale.h>:局部类别  <math.h>:数字常量  <setjmp.h>:非局部goto

<signal.h>  信号  <stdarg.h>:可变参数表  <stdbool.h>:布尔类型的值  <stddef.h>:标准定义  <stdint.h>整型  <stdio.h>标准I/O库

<stdlib.h>实用程序函数  <string.h>字符串操作  <tgmath.h>:通用类型数学宏  <time.h>:时间和日期  <wchar.h>:扩展的多字节和宽字节支持 

<wctype.h>:宽字符分类和映射支持

 

2.2.2 IEEE POSIX

POSIX是一些列由IEEE(Institute of Electrical and Electronics Engineers,电气与电子工程师协会)制定的标准。POSIX指的是可移植的操作系统接口。他原来只是IEEE标准1003.1-1988(操作系统接口),后来扩展称包括很多标记为1003的标准及标准草案,包括shell和实用程序(1003.2)

1003.1操作系统接口标准,该标准的目的是提高应用程序在各种UNIX系统环境的可移植性。它定义了“依从POSIX的”操作系统必须提供的各种服务。该标准已被大多数计算机制造商采用。虽然1003.1标准是以UNIX操作系统为基础的,但是它并不限于UNIX和类UNIX的系统。确实,有些供应专有操作系统的制造商也声称这些系统将依从POSIX(同时还保有他们的所有专有功能)

由于1003.1标准定义了一个接口而不是一种实现,所以并不区分系统调用和库函数。标准中的所有例程都称为函数

POSIX标准定义的必须的头文件

<dirent.h>目录项  <fcntl.h>文件控制  <fnmatch.h>文件名匹配类型  <glob.h>路径名模式匹配类型  <grp.h>组文件  <netdb.h>网络数据库操作

<pwd.h>口令文件  <regex.h>正则表达式  <tar.h>tar归档值  <termios.h>终端I/O  <unistd.h>符号常量  <utime.h>文件时间  

<wordexp.h>字扩展类型  <arpa/inet.h>internet定义  <net/if.h>套接字本地接口  <netinet/in.h>internet地址族  <netinet/tcp.h>传输控制协议定义

<sys/mman.h>内存管理声明  <sys/select.h>select函数  <sys/socket.h>套接字接口   <sys/stat.h>文件状态  <sys/times.h>进程时间

<sys/types.h>基本系统数据类型  <sys/un.h>UNIX域套接字定义  <sys/utsname.h>系统名  <sys/wait.n>进程控制

POSIX标准定义的XSI扩展头文件

<cpio.h>cpio归档值  <dlfcn.h>动态链接  <fmtmsg.h>消息显示结构  <ftw.h>文件树漫游  <iconv.h>代码集转换实用程序  <langinfo.h>语言信息常量

<libgen.h>模式匹配函数定义  <monetary.h>货币类型  <ndbm.h>数据库操作  <nl_types.h>消息类别

。。。

 

。。。

POSIX.1没有包括超级用户这样的概念,代之以规定某些操作要求“适当的特权”,

 

2.2.3 Single UNIX Specification

Single UNIX Specification(单一unix规范)是POSIX.1标准的一个超集,定义了一些附加的接口,这些接口扩展了基本的POSIX.1规范所提供的功能。相应的系统接口全集称为X/OPEN系统接口(XSI,X/Open System Interface)._XOPEN_UNIX符号常量标识了XSI扩展的接口

2.2.4 FIPS

FIPS的含义是联邦信息处理标准(Federal Information Procesing Standard).

POSIX.1 FIPS的影响是:它要球任何希望向美国政府销售POSIX.1兼容的计算机系统的厂商应支持POSIX.1的某些可选功能。因为POSIX.1 FIPS的影响郑逐步减退,所以在本书中我们将不再进一步考虑它

2.3UNIX系统实现

SVR4

4.4BSD

FreeBSD

Linux

Mac OS X

Solaris

2.5限制

编译时限制可在头文件中定义,程序在编译时可以包含这些头文件。但是,运行时限制则要求进程调用一个函数以获得此种限制值

另外,某些限制在一个给定的实现中可能是固定的(因此可以静态地在一个头文件中定义),而在另一个实现上则可能变化的(需要有一个运行时函数调用)

为解决这类问题,提供以下三种限制:

1.编译时限制(头文件)

2.不与文件或目录相关联的运行时限制(sysconf函数)

3.与文件或目录相关联的运行时限制(pathconf和fpathconf函数)

使事情变得更加复杂的是,如果一个特定的运行时限制在一个给定的系统上并不改变,则可将其静态地定义在一个头文件中,但是,如果没有将其定义在头文件中,则应用程序必须调用三个conf函数中的一个,以确定其运行的值

 

2.5.1 ISO C限制

ISO C定义的限制都是编译时限制。

2.5.2 POSIX限制

POSIX.1定义了很多涉及操作系统实现限制的常量,不幸的是,这是POSIX.1中最令人迷惑不解的部分之一

1.不变的最小值

2.不变值:SSIZE_MAX

3.运行时可以增加的值:CHARCLASS_NAME_MAX,COLL_WEIGHTS_MAX,LINE_MAX,NGROUPS_MAX以及RE_DUP_MAX

4.运行时不变的值(可能不确定):ARG_MAX,CHILD_MAX,HOST_NAME_MAX,LOGIN_NAME_MAX,OPEN_MAX,PAGESIZE,RE_DUP_MAX,STREAN_MAXS,

                SYMLOOP_MAX,TTY_NAME_MAX以及TZNAME_MAX

5.路径名可变值(可能不确定):FILESIZEBITS,LINK_MAX,MAX_CANON,MAX_INPUT,NAME_MAX,PATH_MAX,PIPE_BUF以及SYMLINK_MAX

2.5.3 XSI限制

XSI还定义了处理实现限制的下面几个常量:

1.不变最小值:NL_ARGMAX,NL_LANGMAX,NL_MSGMAX,NL_NMAX,NL_SETMAX,NL_TEXTMAX,NZERO,_XOPEN_IOV_MAX,_XOPEN_NAME_MAX,

         _XOPEN_PATH_MAX

2.数值限制:LONG_BIT和WORD_BIT

3.运行时不变值(可能不确定):ATEXIT_MAX.,IOV_MAX以及PAGE_SIZE.

 

2.5.4 sysconf,pathconf和fpathconf函数

运行时限制可通过调用下面三个函数中的一个而取得

#include<unistd.h>

long sysconf(int name);

long pathconf(const char *pathname,int name);

long fpathconf(int filedes,int name);

以_SC_开始的常量用作标识运行时限制的sysconf参数。以_PC_开始的常量用作标识运行时限制的pathconf或fpathconf参数

 

对于pathconf的参数pathname以及fpathconf的参数filedes有一些限制。如果不满足其中任何一个限制,则结果是未定义的

1._PC_MAX_CANON和_PC_MAX_INPUT所引用的文件必须是终端文件

2._PC_LINK_MAX所引用的文件可以是文件或目录。如果是目录,则返回值用于目录本身(而不是用于目录内的文件名项)

3._PC_FILESIZEBITS和_PC_NAME_MAX所引用的文件必须是目录,返回值用于该目录中的文件名

4._PC_PATH_MAX引用的文件必须是目录。当所指定的目录是工作目录时,返回值是相对路径名的最大长度(

5._PA_PIPE_BUF所引用的文件必须是管道,FIFO或目录。在管道或FIFO情况下,返回值是对所引用的管道或FIFO的限制值。对于目录,返回值是对该目录中创建的任意FIFO的限 制值

6._PC_SYMLINK_MAX所引用的文件必须是目录。返回值是该目录中符号链接可能包含的字符串的最大长度

程序清单2_2 打印所有可能的sysconf和pathconf的值

 1 #include"apue.h"
 2 #include<errno.h>
 3 #include<limits.h>
 4 static void pr_sysconf(char*,int);
 5 static void pr_pathconf(char*,char*,int);
 6 int main(int argc,char *argv[])
 7 {
 8     if(argc!=2)
 9     err_quit("usage:a.out<dirname>");
10 #ifdef ARG_MAX
11     printf("ARG_MAX defined to be %d\n",ARG_MAX+0);
12 #else
13     printf("no symbol for ARG_MAX\n");
14 #endif
15 #ifdef _SC_ARG_MAX
16     pr_sysconf("ARG_MAX =",_SC_ARG_MAX);
17 #else
18     printf("no symbol for _SC_ARG_MAX\N");
19 #endif
20 #ifdef MAX_CANON
21     printf("MAX_CANON defined to be %d\n",MAX_CANON+0);
22 #else
23     printf("no symbol for MAX_CANON\n");
24 #endif
25 #ifdef _PC_MAX_CANON
26     pr_pathconf("MAX_CANON =",argv[1],_PC_MAX_CANON);
27 #else
28     printf("no symbol for _PC_MAX_CANON\n");
29 #endif
30     exit(0);
31 }
32 static void pr_sysconf(char *mesg,int name)
33 {
34     long val;
35     fputs(mesg,stdout);
36     errno=0;
37     if((val=sysconf(name))<0){
38     if(errno!=0){
39     if(errno==EINVAL)
40     fputs("(not supported)\n",stdout);
41     else
42     err_sys("sysconf error");
43     }
44     else
45     {
46     fputs("(no limit)\n",stdout);
47     }
48     }
49     else{    
50     printf(" %ld\n",val);
51     }
52 }
53 static void pr_pathconf(char *mesg,char *path,int name)
54 {
55     long val;
56     fputs(mesg,stdout);
57     errno=0;
58     if((val=pathconf(path,name))<0){
59     if(errno!=0){
60     if(errno==EINVAL)
61     fputs("(not supported)\n",stdout);
62     else
63     err_sys("pathconf error,path=%s",path);
64     }else{
65     fputs("(no limit)\n",stdout);
66     }
67     }else{
68     printf("%ld\n",val);
69     }
70 }

2.5.5 不确定的运行时限制

前面已提及某些限制值可能是不确定的。我们遇到的问题是:如果这些限制值没有在头文件<limits.h>中定义,那么在编译时也就不能使用它们。但是,如果它们的值是不确定的,那么在运行时它们可能也是未定义的

处理不确定结果这种情况的正确方法与如何使用所分配的存储空间有关。例如,如果我们为getcwd调用分配空间(返回当前工作目录的绝对路径名),如果分配空间太小,则返回一个出错,并将errno设置为ERANGE。然后可调用realloc来增加分配的空间并重试。不断重复此操作,知道getcwd调用成功执行

程序清单2_3 为路径名动态地分配空间

 1 #include"apue.h"
 2 #include<errno.h>
 3 #include<limits.h>
 4 #ifdef PATH_MAX
 5 static int pathmax=PATH_MAX;
 6 #else
 7 static int pathmax=0;
 8 #endif
 9 
10 #define SUSV3 200112L
11 static long posix_version=0;
12 #define PATH_MAX_GUESS 1024
13 
14 char* path_alloc(int *sizep)
15 {
16     char *ptr;
17     int size;
18     if(posix_version==0)
19     posix_version=sysconf(_SC_VERSION);
20     if(pathmax==0){
21     errno=0;
22     if((pathmax=pathconf("/",_PC_PATH_MAX))<0){
23     if(errno ==0)
24     pathmax=PATH_MAX_GUESS;
25     else
26     err_sys("pathconf error for _PC_PATH_MAX");
27     }
28     else{
29     pathmax++;
30     }
31     }
32     if(posix_version < SUSV3)
33     size=pathmax;
34     if((ptr=malloc(size))==NULL)
35     err_sys("malloc error for pathname");
36     if(sizep!=NULL)
37     *sizep=size;
38     return(ptr);
39 }

 

APUE学习笔记:第二章 UNIX标准化及实现,布布扣,bubuko.com

APUE学习笔记:第二章 UNIX标准化及实现

标签:des   style   blog   color   使用   os   

原文地址:http://www.cnblogs.com/wbingeek/p/3835557.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!