[單刷APUE系列]第二章——Unix標準及實現

目錄

[單刷APUE系列]第一章——Unix基礎知識[1]
[單刷APUE系列]第一章——Unix基礎知識[2]
[單刷APUE系列]第二章——Unix標準及實現
[單刷APUE系列]第三章——文件I/O
[單刷APUE系列]第四章——文件和目錄[1]
[單刷APUE系列]第四章——文件和目錄[2]
[單刷APUE系列]第五章——標準I/O庫
[單刷APUE系列]第六章——系統數據文件和信息
[單刷APUE系列]第七章——進程環境
[單刷APUE系列]第八章——進程控制[1]
[單刷APUE系列]第八章——進程控制[2]
[單刷APUE系列]第九章——進程關係
[單刷APUE系列]第十章——信號[1]express

Unix標準化

Unix編程環境和C程序設計語言是如此的廣泛,並且標準化工做作了很是多,可是20世紀80年代Unix版本種類的劇增以及他們差異的擴大致使跨平臺移植變得愈來愈難,不少用戶都呼籲對其進行標準化。
Unix標準化有四個,ISO C、IEEE POSIX、Single Unix Specification、FIPS編程

ISO C

ISO C標準如今由ISO/IEC的C程序設計語言國際標準工做組維護和開發。ISO C標準的意圖是提供C程序的可移植性,使其能適應於大量的操做系統。標準不但定義了C程序設計語言的語法,還規定了必備的標準庫。
1989年,C程序設計語言的ANSI標準被採納爲國際標準,也是最先的一次標準化過程,目前被稱爲C89標準
1999年,ISO C標準被更新,在C89的基礎上增長了基本數據類型、關鍵字和一些系統函數,這也是目前主流的C語言編譯器標準,即C99標準,是繼C89之後的第二個C語言官方標準。自1999年以來,也有3次技術勘誤用於修正ISO C標準,分別於2001年、2004年和2007年,2011年還更新了C11標準,可是很是遺憾的是,標準審批和實際生產仍是有必定時間延遲,因此C11標準目前還並不是主流。
根據ISO C標準,C程序設計語言有24個頭文件,目前全部的Unix環境都支持這些頭文件。segmentfault

頭文件 說明
<assert.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> 標準輸入輸出
<stdlib.h> 實用函數庫
<string.h> 字符串操做
<tgmath.h> 通用類型數學宏
<time.h> 時間日期支持
<wchar.h> 多字節寬字符支持
<wctype.h> 寬字符分類和映射支持
IEEE POSIX

IEEE POSIX在原書內指的是IEEE 1003.1操做系統接口標準,該標準的1988版本遞交給ISO,最終成爲了國際標準POSIX.1,然後IEEE 1003.1工做組對其做出不少修訂,包括了著名的pthreads多線程接口。POSIX標準不只包含了ISO C標準函數庫,還根據標準要求提供包含了系統調用和庫函數的頭文件,在這裏就不一一列出了。因爲POSIX標準只是定義了操做系統接口而非實現,因此並未區分系統調用和庫函數。其接口分爲兩部分,一部分是強制規定必須的部分,而另一部分是非強制要求的可選部分,多線程

Single Unix Specification

Single Unix Specification是POSIX.1標準的一個超集,它定義了一系列附加接口擴展了POSIX.1的功能,Open Group擁有Unix商標,他們定義了SUS標準,一個系統想要稱爲Unix系統,就必須實現這些接口,而且經過驗收性測試,才能獲得Unix商標使用權,其中就包括了Mac OS X系統,而Linux雖然實現了這些接口,可是從未提出過申請,因此Linux沒有獲得過Unix商標。app

FIPS

FIPS是聯邦信息處理標準,實際上並無什麼卵用,只是美國政府採購的標準,後來還被撤回了。ide

限制

在作Unix環境開發時,咱們常常遇到跨平臺編譯的問題,例如:x86_64和x86字長的不一樣致使的數據類型長度不一致。不一樣Unix版本對接口實現程度不一致。其中最重要的問題就是編譯時限制和運行時限制。
編譯時限制咱們能夠經過在頭文件中進行宏定義,而後使用include指令包含這些頭文件。也能夠向編譯器傳入-Dmacroname=value傳入宏定義參數來動態定義這些限制。
運行時限制則要求進程調用庫函數來得到系統內置的參數。
Unix系統提供了一下兩種限制:函數

  1. 編譯時限制(頭文件)測試

  2. 運行時限制:sysconfpathconffpathconfui

除了Unix系統要求的限制,C程序設計語言的ISO C標準也提供了編譯時限制,全部的限制都被放在<limits.h>頭文件中,可是注意,這些限制的具體值其實是由Unix系統規定的而不是C語言規定。
例如<inttypes.h>頭文件,開發者能夠利用它提供的常量、宏和派生類型使其代碼與顯式指定大小的數據項兼容,而無論編譯環境如何。衆所周知,因爲x86_64和x86之間的區別,整形類型所使用的內存空間是不一樣的,也就是說,咱們極可能濫用整形致使邊界溢出的問題,在實際開發中,推薦的方法是使用定長的整形,而不是int和long,而這個文件也包含了格式化字符串所須要的描述參數的宏定義,極大地方便了開發者的使用。
Unix系統標準規定的全部限制只包含兩種:POSIX限制和XSI限制,對於開發者來講,這兩種限制沒有任何區別,都是以一樣的方式能夠獲取。
正如前文所言,限制分爲編譯時限制和運行時限制,運行時限制能夠經過下列三個函數獲取this

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

順便更正一下原著關於fpathconf函數返回值的錯誤,原著是log,其實是long。

The pathconf() and fpathconf() functions provides a method for applications to determine the current value of a configurable system limit or option variable associated with a pathname or file descriptor.

很是簡單易懂,這兩個函數實際上沒什麼區別,只是用文件描述符來代替文件路徑罷了。

_PC_LINK_MAX
             The maximum file link count.

     _PC_MAX_CANON
             The maximum number of bytes in terminal canonical input line.

     _PC_MAX_INPUT
             The minimum maximum number of bytes for which space is available in a terminal input queue.

     _PC_NAME_MAX
             The maximum number of bytes in a file name.

     _PC_PATH_MAX
             The maximum number of bytes in a pathname.

     _PC_PIPE_BUF
             The maximum number of bytes which will be written atomically to a pipe.

     _PC_CHOWN_RESTRICTED
             Return 1 if appropriate privileges are required for the chown(2) system call, otherwise 0.

     _PC_NO_TRUNC
             Return 1 if file names longer than KERN_NAME_MAX are truncated.

     _PC_VDISABLE
             Returns the terminal character disabling value.

     _PC_XATTR_SIZE_BITS
             Returns the number of bits used to store maximum extended attribute size in bytes.  For example, if the maximum attribute size
             supported by a file system is 128K, the value returned will be 18.  However a value 18 can mean that the maximum attribute size
             can be anywhere from (256KB - 1) to 128KB.  As a special case, the resource fork can have much larger size, and some file system
             specific extended attributes can have smaller and preset size; for example, Finder Info is always 32 bytes.

上面就是pathconf函數族可能獲取的值,具體的能夠參考<unistd.h>

_SC_ARG_MAX
             The maximum bytes of argument to execve(2).

     _SC_CHILD_MAX
             The maximum number of simultaneous processes per user id.

     _SC_CLK_TCK
             The frequency of the statistics clock in ticks per second.

     _SC_IOV_MAX
             The maximum number of elements in the I/O vector used by readv(2), writev(2), recvmsg(2), and sendmsg(2).

     _SC_NGROUPS_MAX
             The maximum number of supplemental groups.

     _SC_NPROCESSORS_CONF
             The number of processors configured.

     _SC_NPROCESSORS_ONLN
             The number of processors currently online.

     _SC_OPEN_MAX
             The maximum number of open files per user id.

     _SC_PAGESIZE
             The size of a system page in bytes.

     _SC_STREAM_MAX
             The minimum maximum number of streams that a process may have open at any one time.

     _SC_TZNAME_MAX
             The minimum maximum number of types supported for the name of a timezone.

     _SC_JOB_CONTROL
             Return 1 if job control is available on this system, otherwise -1.

     _SC_SAVED_IDS
             Returns 1 if saved set-group and saved set-user ID is available, otherwise -1.

     _SC_VERSION
             The version of IEEE Std 1003.1 (``POSIX.1'') with which the system attempts to comply.

     _SC_BC_BASE_MAX
             The maximum ibase/obase values in the bc(1) utility.

     _SC_BC_DIM_MAX
             The maximum array size in the bc(1) utility.

     _SC_BC_SCALE_MAX
             The maximum scale value in the bc(1) utility.

     _SC_BC_STRING_MAX
             The maximum string length in the bc(1) utility.

     _SC_COLL_WEIGHTS_MAX
             The maximum number of weights that can be assigned to any entry of the LC_COLLATE order keyword in the locale definition file.

     _SC_EXPR_NEST_MAX
             The maximum number of expressions that can be nested within parenthesis by the expr(1) utility.

     _SC_LINE_MAX
             The maximum length in bytes of a text-processing utility's input line.

     _SC_RE_DUP_MAX
             The maximum number of repeated occurrences of a regular expression permitted when using interval notation.

     _SC_2_VERSION
             The version of IEEE Std 1003.2 (``POSIX.2'') with which the system attempts to comply.

     _SC_2_C_BIND
             Return 1 if the system's C-language development facilities support the C-Language Bindings Option, otherwise -1.

     _SC_2_C_DEV
             Return 1 if the system supports the C-Language Development Utilities Option, otherwise -1.

     _SC_2_CHAR_TERM
             Return 1 if the system supports at least one terminal type capable of all operations described in IEEE Std 1003.2 (``POSIX.2''),
             otherwise -1.

     _SC_2_FORT_DEV
             Return 1 if the system supports the FORTRAN Development Utilities Option, otherwise -1.

     _SC_2_FORT_RUN
             Return 1 if the system supports the FORTRAN Runtime Utilities Option, otherwise -1.

     _SC_2_LOCALEDEF
             Return 1 if the system supports the creation of locales, otherwise -1.

     _SC_2_SW_DEV
             Return 1 if the system supports the Software Development Utilities Option, otherwise -1.

     _SC_2_UPE
             Return 1 if the system supports the User Portability Utilities Option, otherwise -1.

經常使用的就是這些,另外可能還有一些非標準參數,這裏就不在敘述。想必你們也看出來了,以_SC_開頭的就是sysconf,以_PC_開頭的就是pathconf
關於原著中不肯定的運行時限制,原文寫的很是囉嗦,實際上沒有什麼卵用,由於雖然POSIX規定了不少限制,可是不少都沒有被實際實現,因此碰到這種狀況,只能使用條件編譯、循環嘗試、錯誤碼判斷等hack手段來搞定。

功能測試宏

因爲Unix版本衆多,各自的實現也不一樣,幾乎每一個Unix實現都自帶了自定義的功能選項,爲了保證只使用POSIX標準規範定義,咱們可使用_POSIX_C_SOURCE宏定義和_XOPEN_SOURCE宏定義,這也被稱爲功能測試宏。咱們能夠給C編譯器傳入-Dmacroname=value的形式,也能夠在頭文件中設置宏定義。

基本系統數據類型

爲了保證跨平臺開發使用一樣的類型,Unix標準要求系統提供基本數據類型以供開發者使用,這些數據類型都已_t結尾,根據系統字長和平臺的不一樣,他們具體的實現空間也不一樣,可是至少保證了不會由於系統不一樣而去關注具體實現細節。

相關文章
相關標籤/搜索