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

2.2UNIX标准化ios

2.2.1 ISO C正则表达式

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

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

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

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

ISO C标准定义的头文件:tcp

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

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

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

<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 }
相关文章
相关标签/搜索