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 }
相關文章
相關標籤/搜索