[單刷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編程環境和C程序設計語言是如此的廣泛,並且標準化工做作了很是多,可是20世紀80年代Unix版本種類的劇增以及他們差異的擴大致使跨平臺移植變得愈來愈難,不少用戶都呼籲對其進行標準化。
Unix標準化有四個,ISO C、IEEE POSIX、Single Unix Specification、FIPS編程
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 1003.1操做系統接口標準,該標準的1988版本遞交給ISO,最終成爲了國際標準POSIX.1,然後IEEE 1003.1工做組對其做出不少修訂,包括了著名的pthreads多線程接口。POSIX標準不只包含了ISO C標準函數庫,還根據標準要求提供包含了系統調用和庫函數的頭文件,在這裏就不一一列出了。因爲POSIX標準只是定義了操做系統接口而非實現,因此並未區分系統調用和庫函數。其接口分爲兩部分,一部分是強制規定必須的部分,而另一部分是非強制要求的可選部分,多線程
Single Unix Specification是POSIX.1標準的一個超集,它定義了一系列附加接口擴展了POSIX.1的功能,Open Group擁有Unix商標,他們定義了SUS標準,一個系統想要稱爲Unix系統,就必須實現這些接口,而且經過驗收性測試,才能獲得Unix商標使用權,其中就包括了Mac OS X系統,而Linux雖然實現了這些接口,可是從未提出過申請,因此Linux沒有獲得過Unix商標。app
FIPS是聯邦信息處理標準,實際上並無什麼卵用,只是美國政府採購的標準,後來還被撤回了。ide
在作Unix環境開發時,咱們常常遇到跨平臺編譯的問題,例如:x86_64和x86字長的不一樣致使的數據類型長度不一致。不一樣Unix版本對接口實現程度不一致。其中最重要的問題就是編譯時限制和運行時限制。
編譯時限制咱們能夠經過在頭文件中進行宏定義,而後使用include
指令包含這些頭文件。也能夠向編譯器傳入-Dmacroname=value
傳入宏定義參數來動態定義這些限制。
運行時限制則要求進程調用庫函數來得到系統內置的參數。
Unix系統提供了一下兩種限制:函數
編譯時限制(頭文件)測試
運行時限制:sysconf
、pathconf
和fpathconf
ui
除了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
結尾,根據系統字長和平臺的不一樣,他們具體的實現空間也不一樣,可是至少保證了不會由於系統不一樣而去關注具體實現細節。