頁次 | 類型 | 修訂內容 | 修訂日期 | 版次 | 提供者 |
無頁碼 | 微調 | 保持符號的一致性,在書本開頭的【專家對本書的讚譽】 ,其中第2頁的底部最後一行:
原本是: -LOÏC DOMAIGNÉ, CHIEF SOFTWARE ARCHITECT (EMBEDDED), CORPULS.COM
將標點符號修改為大寫的逗號: -LOÏC DOMAIGNÉ,CHIEF SOFTWARE ARCHITECT (EMBEDDED),CORPULS.COM
| 2016/10/29 | 初版 | Jensen Chou |
無頁碼 | 微調 | 在書本開頭的【專家對本書的讚譽】 ,其中第3頁的第7行:
原本是: 「一本超水準的書,內含經典珍藏著作 Advanced Programming in the UNIX ...
修改為: 「一本超乎水準的書,內含經典珍藏著作 Advanced Programming in the UNIX ...
| 2016/10/29 | 初版 | Aaron Liao |
xxix | 微調 | 在 Linux 核心與 C 函式庫的版本下方的第二段、第2行:
原本是: 標出與其他 glibc 2.x 版本的差異。
修改為: 標示出與其他 glibc 2.x 版本的差異。
| 2016/10/22 | 初版 | Aaron Liao |
xxxi | 微調 | 此頁的倒數第5行中間:
原本是: ...,他不僅熱情投入並鼓勵作者,...
修改為: ...,他還熱情投入並鼓勵作者,...
| 2016/10/22 | 初版 | Aaron Liao |
xxxii | 訂正 | 此頁的第2行:
原本是: 與終端機、登入記帳、行程群組、作業階段(session)....
修改為:
與終端機、登入記帳、行程群組、作業階段(session)....
| 2016/10/22 | 初版 | Aaron Liao |
p15 | 微調 | 在此頁的第10行(SUSv3基本規範的第三個部分):
原本是: Shell 和實用工具(XCU):明確定義了 shell 和各種 UNIX 命令的行為。...
修改為: Shell 和實用工具(XCU):明確定義了 shell 和各種 UNIX 指令的行為。...
| 2016/11/14 | 初版 | Aaron Liao |
p30 | 語意 | 此頁中間的符號連結(Symbolic link)第2行開始:
原本是: 在目錄清單中的內容是一個「檔名+指標」的項目,而符號連結則是有特殊標示的檔案,內容是另一個檔案的檔名。(換句話說,一個符號連結在目錄中的內容是「檔名+指標」的一個項目,指標所指向的檔案,其內容 是個字串,此字串是另一個檔案的檔名。)所謂「另一個檔案」通常稱為符號連結的目標(target),通常會說符號連結是「指向」或「參考、參照」目的檔案。在多數情況下,只要在系統呼叫指定了路徑名稱(pathname),核心會自動解參考(dereference)該路徑名稱的每個符號連結,以符號連結所指向的檔案名來替換符號連結。
修改的地方: 在目錄清單中的內容是一個「檔名+指標」項條目(entry),而符號連結則是一個有特殊標示記的檔案,內容是另一個檔案的檔名。(換句話說,一個符號連結在目錄中也有一個的內容是「檔名+指標」的一個項條目,而其指標指向另一個檔案的檔名,檔名是字串格式。指標所指向的檔案,其內容 是個字串,此字串是另一個檔案的檔名。)所謂「另一個檔案」通常稱為符號連結的目標(target),通常會說符號連結是「指向」或「參考、參照」到一個目的檔案。在多數情況下,只要在系統呼叫指定了路徑名稱(pathname),核心會自動解參考(dereference,或稱提取)該路徑名稱的每個符號連結,以符號連結所指向的檔案名來替換符號連結。
修改後的全文: 在目錄清單中的內容是一個「檔名+指標」條目(entry),而符號連結則是一個有特殊標記的檔案,內容是另一個檔案的檔名。(換句話說,一個符號連結在目錄中也有一個「檔名+指標」的條目,而其指標指向另一個檔案的檔名,檔名是字串格式。)所謂「另一個檔案」通常稱為符號連結的目標(target),通常會說符號連結是「指向」或「參考、參照」到一個目的檔案。在多數情況下,只要在系統呼叫指定了路徑名稱(pathname),核心會自動解參考(dereference,或稱提取)該路徑名稱的每個符號連結,以符號連結所指向的檔名來替換符號連結。
摘要: 簡而言之,這段是要表達,符號連結這類的檔案本身只是指向另一個檔案,但對於目錄中的條目內容而言,符號連結與一般的檔案是相同的。而存取的檔案之路徑名稱中若包含著符號連結,則系統核心會自動解析,將符號連結檔案轉換為連結的對應檔案。
| 2016/10/22 | 初版 | Aaron Liao |
p31 | 訂正 | 此頁的第三行,在此行中間的逗點前方,將【檔案】修正為【檔名】。
| 2017/07/21 | 初版 | YouChih Wang |
p41 | 微調 | 保持譯詞的一致性,先找出頁面下方的標題 - 2.12 執行緒(Thread),在標題上方的那兩行:
原本是: (signal mask)中,對其進行阻斷(block)。若訊號在被阻斷時產生,則仍會被擱置,直到它解除阻斷(即從訊號遮罩中移除訊號)。
修改為: (signal mask)中,對其進行阻塞(block)。若訊號在被阻塞時產生,則仍會被擱置,直到它解除阻塞(即從訊號遮罩中移除訊號)。
| 2016/10/24 | 初版 | Aaron Liao |
p44 | 微調 | 保持譯詞的一致性,先找出頁面中間的標題 - 2.17 客戶端/伺服器架構,在此節的第3行:
原本是: 客戶端:向伺服器發送請求消息,...
修改為: 客戶端:向伺服器發送請求訊息,...
| 2016/10/24 | 初版 | Aaron Liao |
p47 | 微調 | 第1行:
原本是: 本章涵蓋各式系統程式設計所預先需要的主題。我們先導讀系統呼叫及詳細敘述
修改為: 本章涵蓋各式系統程式設計所預先需要的主題。我們先簡介系統呼叫及詳細敘述
| 2016/10/28 | 初版 | Aaron Liao |
p49 | 微調 | 第1行:
原本是: 可以系統呼叫編號檢索一張系統呼叫服務常式表格 ...
修改為: 可用系統呼叫編號檢索一張系統呼叫服務常式表格 ...
| 2016/10/28 | 初版 | Aaron Liao |
p51 | 訂正 | 在 3.2 節的第6行:
原本是: 有些函式庫函式會架構於系統呼叫之上。例如:fopen 函式庫函式實際上是使用open()系統呼叫開啟檔案。
修改為: 有些函式庫函式會架構於系統呼叫之上。例如:fopen() 函式庫函式實際上是使用open()系統呼叫開啟檔案。
| 2016/10/28 | 初版 | Aaron Liao |
p52 | 訂正 | 在中間的 gnu_get_libc_version 函式原型方框往上倒數第2行︰
原本是: 處理這個問題,程式可以在執行期呼叫gnu_get_libc_version()函式,已取得可用的 glibc 版本。
修改為: 處理這個問題,程式可以在執行期呼叫gnu_get_libc_version()函式,用以取得可用的 glibc 版本。
| 2016/10/28 | 初版 | Aaron Liao |
p53 | 微調 | 在第2行:
原本是: UNIX與Linux程式範例之後),但是這個地方不該節省。...
修改為: UNIX與Linux程式範例之後),但是這個地方不該省略。...
| 2016/10/28 | 初版 | Aaron Liao |
p59 | 微調 | 此頁的第1行:
原本是: 函式 fatal() 用在診斷通用錯誤,包含沒有設定errno的函式庫函式錯誤。
修改為: 函式 fatal() 用在診斷通用錯誤,包含函式庫函式沒有設定errno的函式庫函式這類錯誤。
| 2016/10/28 | 初版 | Aaron Liao |
p73 | 微調 | 在此頁中間的地方:
原本是: 因此,使用下列的結構初始器(initializer)是不可攜的:
修改為: 因此,使用下列的結構初始器(initializer)是不可攜的寫法:
| 2016/10/28 | 初版 | Aaron Liao |
p73 | 訂正 | 在此頁的最後一段:
原本是: 若我們想要將標準結構的內容寫入檔案,則也須可量標準結構的成員順序。為了可攜性,我們不能直接將結構以二進位整個寫入,而是以特定順序,個別寫入結構欄位(或是以文字格式)。
修改的地方: 若我們想要將標準結構的內容寫入檔案,則也須可考量標準結構的成員順序。為了可攜性,我們不能直接將結構以二進位整個寫入,而是以特定順序,個別將寫入結構欄位寫入(或是使用以文字格式)。
修改後的句子: 若我們想要將標準結構的內容寫入檔案,則也須考量標準結構的成員順序。為了可攜性,我們不能直接將結構以二進位整個寫入,而是以特定順序,個別將結構欄位寫入(或是使用文字格式)。
| 2016/10/28 | 初版 | Aaron Liao |
p75 | 語意 | 習題3-1:
原本是: 當使用Linux透有的reboot()系統呼叫以重新開啟系統時,第二個參數:magic2必須設定為魔術號碼組(magic number set)的某個數字(如:LINUX_REBOOT_MAGIC2)。這些數字何者最顯著呢?(將它們轉換為十六進位可以得到線索)。
修改的地方: 當使用Linux透特有的reboot()系統呼叫來以重新開啟動系統時,第二個參數:magic2必須設定為一組魔術號碼組(magic number set)中的某個數字(如:LINUX_REBOOT_MAGIC2)。這些數值的意義為何呢這些數字何者最顯著呢?(將它們轉換為十六進位可以得到線索)。
修改後的句子: 當使用Linux特有的reboot()系統呼叫來重新啟動系統時,第二個參數:magic2必須設定為一組魔術號碼(magic number set)中的某個數字(如:LINUX_REBOOT_MAGIC2)。這些數值的意義為何呢?(將它們轉換為十六進位可以得到線索)。
| 2016/10/28 | 初版 | Aaron Liao |
p78 | 微調 | 維持譯詞的一致性,將【返回】修改為【傳回】:
在倒數第2行:
原本是: write() 呼叫的返回值為 ...
修改為: write() 呼叫的傳回值為 ...
在倒數第4行:
原本是: ... 則返回值為 0。
修改為: ... 則傳回值為 0。
在倒數第5行:
原本是: ... read() 呼叫的返回值為實際讀取到的位元
修改為: ... read() 呼叫的傳回值為實際讀取到的位元
在倒數第12行:
原本是: ... 並返回檔
修改為: ... 並傳回檔
| 2016/10/29 | 初版 | Aaron Liao |
p81 | 微調 | 維持譯詞的一致性,將【返回】修改為【傳回】:
在第2行:
原本是: 其進行解參考,如果呼叫成功,則 open() 將返回一個檔案描述符,...
修改為: 其進行解參考,如果呼叫成功,則 open() 將傳回一個檔案描述符,...
在第3行:
原本是: 函式呼叫中代表該檔案。若發生錯誤,則返回 -1,...
修改為: 函式呼叫中代表該檔案。若發生錯誤,則傳回 -1,...
在表 4-2 下方那一行:
原本是: 15.4 節將詳細描述檔案權限。之後,讀者會瞭解到新建檔案的存取權限不僅依賴
修改為: 15.4 節將詳細描述檔案權限。之後,讀者會瞭解到新建檔案的存取權限不僅取決
| 2016/10/30 | 初版 | Aaron Liao |
p82 | 微調 | 維持譯詞的一致性,將【返回】修改為【傳回】,在頁面中間的第一個標題:
原本是: open() 呼叫所返回的檔案描述符數值 SUSv3規定,如果呼叫 open() 成功,必須保證其返回值為行程中最小的未用檔案描述符
修改為: open() 呼叫所傳回的檔案描述符數值 SUSv3規定,如果呼叫 open() 成功,必須保證其傳回值為行程中最小的未用檔案描述符
| 2016/10/30 | 初版 | Aaron Liao |
p82 | 訂正 | 4.3.1 節標題下方第4行:
原本是: 後一列顯示常數的標準化是符合 SUSv3 還是 SUSv4。
修改為: 後一行顯示常數的標準化是符合 SUSv3 還是 SUSv4。
| 2016/10/29 | 初版 | Aaron Liao |
p84 | 微調 | 在頁面上方的 O_ASYNC 旗標的第1行:
原本是: 當對於 open() 呼叫所返回的檔案描述符可以進行 I/O 操作時,...
修改為: 當可對於 open() 呼叫所返傳回的檔案描述符可以進行 I/O 操作時,... | 2016/10/30 | 初版 | Aaron Liao |
p85 | 微調 | 找到 O_DIRECTORY 旗標,在此段落的第1行:
原本是: 如果 pathname 參數並非目錄,則返回錯誤 ...
修改為: 如果 pathname 參數並非目錄,則傳回錯誤 ...
找到 O_DSYNC 旗標:
原本是: O_DSYNC(自 Linux 2.6.33 版本開始支持)
修改為: O_DSYNC(自 Linux 2.6.33 版本開始提供)
找到 O_EXCL 旗標
原本是: 此旗標與 O_CREAT 旗標結合使用表示如果檔案已經存在,則不會開啟檔案,且 open()呼叫失敗,並返回錯誤,錯誤代號errno為EEXIST。換言之,此旗標確保了呼叫者(open( )的呼叫行程)就是建立檔案的行程。檢查檔案存在與否和建立檔案這兩步驟屬於同一原子操作。5.1節將討論原子操作的概念。如果在flags參數中同時指定了O_CREAT和O_EXCL旗標,且pathname參數是符號連結,則open()函式呼叫失敗(錯誤代號errno為EEXIST)。SUSv3之所以如此規定,是要求有特權的應用程式在已知目錄下建立檔案,從而消除了如下安全隱患,使用符號連結開啟檔案會導致在另一位設定建立檔案(例如,系統目錄)。
修改的地方: 此旗標與 O_CREAT 旗標結合使用表示:如果檔案已經存在,則不會開啟檔案,且 open()呼叫會失敗,並返傳回錯誤,錯誤代號errno為EEXIST。換言之,此旗標確保了呼叫者(open( )的呼叫行程)就是建立檔案的行程。檢查檔案存在與否和建立檔案這兩步驟屬於同一個原子式操作。5.1節將討論原子操作的概念。如果在 flags 參數中同時指定了O_CREAT和O_EXCL旗標,而且pathname參數是符號連結,則open()函式呼叫會失敗(錯誤代號errno為EEXIST)。SUSv3之所以如此規定,是為了讓要求有特權的應用程式在已知目錄下建立檔案,從而消除了如下安全隱患,使用符號連結開啟檔案會導致在另一位設定建立檔案而不會因為符號連結而在不同的位置建立檔案(例如,系統目錄)。
修改後的句子:
此旗標與 O_CREAT 旗標結合使用表示:如果檔案已經存在,則不會開啟檔案,且 open()呼叫會失敗,並傳回錯誤,錯誤代號errno為EEXIST。換言之,此旗標確保了呼叫者(open( )的呼叫行程)就是建立檔案的行程。檢查檔案存在與否和建立檔案這兩步驟屬於同一個原子式操作。5.1節將討論原子操作的概念。如果在 flags 參數中同時指定了O_CREAT和O_EXCL旗標,而且pathname參數是符號連結,則open()函式呼叫會失敗(錯誤代號errno為EEXIST)。SUSv3之所以如此規定,是為了讓有特權的應用程式在已知目錄下建立檔案,而不會因為符號連結而在不同的位置建立檔案(例如,系統目錄)。
找到 O_NOATIME 旗標
原本是: 在讀檔案時,不更新檔案的最近存取時間(15.1 節中所描述的st_atime屬性)。要使用該旗標,要麼呼叫行程的有效使用者ID必須與檔案的擁有者相匹配,要麼行程需要擁有特權(CAP_FOWNER)。否則,open()呼叫失敗,並返回錯誤,錯誤代號errno為EPERM。
修改為: 在讀檔案時,不更新檔案的最近存取時間(15.1 節中所描述的st_atime屬性)。要使用該旗標,要麼則呼叫行程的有效使用者ID必須與檔案的擁有者相匹配,要麼或是行程需要擁有特權(CAP_FOWNER)。否則,open()呼叫會失敗,並返傳回錯誤,錯誤代號errno為EPERM。
| 2016/10/30 | 初版 | Aaron Liao |
p85 | 訂正 | 找到 O_LARGEFILE 旗標,在此段落的第3行:
原本是: ... 此旗標在諸如 Alpha、IA-64 之類的 64 位 Linux 實作中是無效的。 ...
修改為: ... 此旗標在諸如 Alpha、IA-64 之類的 64 位元 Linux 實作中是無效的。 ...
| 2016/10/30 | 初版 | Aaron Liao |
p86 | 微調 | 找到 O_NOFOLLOW 旗標,在此段落的第 3 行:
原本是: 屬於符號連結,則 open() 函式將返回失敗 ...
修改為: 屬於符號連結,則 open() 函式將傳回失敗 ...
找到 4.3.2 標題 open() 呼叫的錯誤,在此段落的第1行:
原本是: 若開啟檔案時發生錯誤,open() 將返回 -1,...
修改為: 若開啟檔案時發生錯誤,則open() 將傳回 -1,...
| 2016/10/30 | 初版 | Aaron Liao |
p87 | 微調 | 找到 EISDIR 旗標:在此段落的第1行:
原本是: 所指定的檔案屬於目錄,而呼叫者企圖開啟該檔案進行寫入操作。不允許這種用法。
修改為: 所指定的檔案屬於目錄,而呼叫者企圖開啟該檔案進行寫入操作,這是不被允許的用法。
| 2016/10/30 | 初版 | Aaron Liao |
p87 | 訂正 | 找到 ENOENT 旗標:
原本是: 檔案不存在,且未指定O_CREAT旗標或指定了 O_CREAT旗標,但pathname參數所指定路徑的某個目錄不存在,或者pathname參數為符號連結,而該連結指向的檔案不存在(空連結)。
修改為: 檔案不存在,且未指定O_CREAT旗標。或指定了 O_CREAT旗標,但pathname參數所指定路徑的某個目錄不存在,或者pathname參數為符號連結,而該連結指向的檔案不存在(懸空連結)。
| 2016/10/30 | 初版 | Aaron Liao |
p88 | 微調 | 找到標題 4.4 讀取檔案內容:read(),下方的第一行:
原本是: read() 系統呼叫從檔案描述符 fd 所代表的開啟檔案中讀取資料。
修改為: read() 系統呼叫從檔案描述符 fd 所代表的已開啟檔案中讀取資料。
此頁面的最後一行:
原本是: 而言,這有可能是因為目前讀取位置靠近檔案結尾部。
修改為: 而言,這有可能是因為目前讀取位置靠近檔案結尾部。
此頁面下列所述的返回都修改為傳回:
1. 位於 creat() 函式原型下方的第2行。 2. 位於 read() 函式原型下方的第4行、第6行、第7行、第8行。
| 2016/10/30 | 初版 | Aaron Liao |
p89 | 微調 | 找到第 3 行:
原本是: 預設情況下從終端讀取字元,一遇到分行符號(\n),read()呼叫就會結束。
修改為: 預設情況下從終端讀取字元,一遇到換行符號(\n),read()呼叫就會結束。
在頁面中間的那段文字,此段落的倒數第3行:
原本是: ... 在字串尾部追加代表字串結束的空字元。如果輸入緩衝區的結尾處需要一個表示終止的空字元,必須明確追加。 修改為: ... 在字串尾部附加代表字串結束的空字元。如果輸入緩衝區的結尾處需要一個表示終止的空字元,必須明確附加。
| 2016/10/30 | 初版 | Aaron Liao |
p90 | 微調 | 將位於 write() 函式原型下方第4行的返回修改為傳回:
原本是: 如果 write() 呼叫成功,將返回實際寫入檔案的位元組數,該返回值可能小於
修改為: 如果 write() 呼叫成功,將傳回實際寫入檔案的位元組數,該傳回值可能小於
在 close() 函式原型的下方,第二行:
原本是: 明確關閉不再需要的檔案描述符是良好的程式設計習慣,會使程式碼在後續修改時更具可讀性,也更可靠。進而言之,檔案描述符屬於有限資源,因此檔案描述符關閉失敗可能會導致一個行程將檔案描述符資源消耗殆盡。
修改為: 明確關閉不再需要的檔案描述符是良好的程式設計習慣,會使程式碼在後續修改時更具可讀性,也更可靠。進而言之,此外,檔案描述符屬於有限資源,因此若沒有關閉檔案描述符關閉失敗可能,則會導致一個行程將檔案描述符資源消耗殆盡。
| 2016/10/30 | 初版 | Aaron Liao |
p92 | 微調 | 在圖 4-1 下方的第4行:
原本是: 如果 whence 參數值為 SEEK_CUR 或 SEEK_END,offset 參數可以為正數也可以為負數;如果 whence 參數值為 SEEK_SET ,offset 參數必須為非負數。
修改為: 如果 whence 參數值為 SEEK_CUR 或 SEEK_END,則 offset 參數可以為正數也可以為負數;如果 whence 參數值為 SEEK_SET ,則 offset 參數必須為非負數。
| 2016/10/30 | 初版 | Aaron Liao |
p93 | 微調 | 1. 將此頁第1行的返回修改為傳回。
2. 找到標題【檔案空洞(file hole)】,並將下方第二行的返回修改為傳回。
| 2016/10/30 | 初版 | Aaron Liao |
p94 | 微調 | 找到標題【範例程式】,此段落的第四行
原本是:
- soffset:從檔案開頭檢索到 offset 位元組的位置位設定。
修改為:
- soffset:從檔案開頭檢索到 offset 個位元組的位置
位設定。
| 2016/10/30 | 初版 | Aaron Liao |
p96 | 微調 | 此頁面上方程式碼之下的第1行:
原本是: 下面的 shell 作業階段示範了列表4-3程式的使用,還顯示了從檔案空洞中讀取位元組時的情況:
修改為: 下面的 shell 作業階段示範了列表4-3程式的使用,還顯示了從檔案空洞中讀取一些位元組資料時的情況:
| 2016/10/30 | 初版 | Aaron Liao |
p97 | 微調 | 找到標題 4.9 小結,第三段:
原本是: 對於已開啟的每個檔案,核心都會維護一個檔案偏移量,這決定了下一次讀或寫入操作的起始位置。讀取和寫入操作會隱式修改檔案偏移量。使用lseek()函式可以直接將檔案偏移量設定為檔案中或檔案結尾後的任一位置。在檔案原結尾處之後的某一位置寫入資料將導致檔案空洞。從檔案空洞處讀取檔案將返回內容全0的位元組資料。
修改為: 對於已開啟的每個檔案,核心都會維護一個檔案偏移量,這決定了下一次讀取或寫入操作的起始位置。讀取和寫入操作會隱含地(implicitly)修改檔案偏移量。使用lseek()函式可以直接將檔案偏移量設定為檔案中或檔案結尾後的任一位置。在檔案原結尾處之後的某一位置寫入資料將導致檔案空洞。從檔案空洞處讀取檔案將傳回內容全0的位元組資料。
找到習題 4-2:
原本是: 4.2. 設計一個類似於cp指令的程式,當使用該程式複製一個包含空洞(連續的空位元組)的普通檔案時,要求目的檔案的空洞與原始檔案保持一致。
修改的地方: 4.2. 設計一個類似於cp指令的程式,當使用該程式複製一個包含空洞(連續的空位元組)的普通檔案時,要求也要在目的檔案相對應的位置建立的空洞與原始檔案保持一致。
修改後的句子: 4.2. 設計一個類似於cp指令的程式,當使用該程式複製一個包含空洞(連續的空位元組)的普通檔案時,也要在目的檔案相對應的位置建立空洞。
| 2016/10/30 | 初版 | Aaron Liao |
p103 | 訂正 | 此頁的第7行:
原本是: 述的非原子式循序呼叫,結果一定會如所剛才所說的,造成檔案毀損 ...
修改為: 述的非原子式循序呼叫,結果一定會如所剛才所說的,造成檔案毀損 ...
| 2016/10/30 | 初版 | Aaron Liao |
p104 | 訂正 | 此頁中間,大約第14行:
原本是: 是 O_APPEND、O_NONBLOCK、O-NOATIME、O_ASYNC 與 O_DIRECT。...
修改為: 是 O_APPEND、O_NONBLOCK、O_NOATIME、O_ASYNC 與 O_DIRECT。...
| 2016/10/30 | 初版 | Aaron Liao |
p105 | 語意 | 找到 5.4 節的第 2 行:
原本是: 這些檔案描述符可以在同一個行程或是不同的行程中開啟。
修改為: 這些檔案描述符可能是在同一個行程或是不同的行程中開啟的。
找到 5.4 節的第 8 行:
原本是: 核心為每個行程維護一個開啟檔案描述符表格,此表中的每筆紀錄記載著單一檔案描述符的相關資訊,包含:
- 一組控制檔案描述符操作的旗標(這種旗標只有一組,即我們在 27.4 節所述的 close-on-exec 旗標)。
- 一個指向開啟檔案描述符的參考(reference)。
核心維護整個系統的每個開啟檔案描述符表格。(此表有時會參考開啟檔案表,而表格內的紀錄有時稱為 open file handle)。一個開啟檔案描述符會儲存所有與開啟檔案的相關資訊,包含:
修改為: 核心為每個行程維護一個開啟檔案描述符表格,此表中的每筆紀錄記載著單一檔案描述符的相關資訊,包含:
- 一組控制檔案描述符操作的旗標(這種旗標只有一個
組,即我們在 27.4 節所述的 close-on-exec 旗標)。 - 一個指向開啟檔案描述符的參考(reference)。
核心會維護一張表格,包含整個系統全部的每個開啟檔案描述符表格。(此表有時會當作參考開啟檔案表來參考,而表格內的那些紀錄有時會稱為 open file handle)。一個開啟檔案描述符會儲存所有與開啟檔案的相關的資訊,包含:
| 2016/10/30 | 初版 | Aaron Liao |
p120 | 訂正 | 在倒數第 8 行:
原本是: 輸出作為參數。其次,有些程式還將單個「-」符解釋為表示命令列選項結束的分隔符號。
修改為: 輸出作為參數。其次,有些程式還將單個「-」符號解釋為表示命令列選項結束的分隔符號。
| 2016/10/30 | 初版 | Aaron Liao |
p121 | 訂正 | 在 mkstemp() 函式原型下方的第7行:
原本是: 通常,開啟暫存檔案不久,程式就會使用 unlink 系統呼叫(參考18.3節)將
修改為: 通常,開啟暫存檔案不久,程式就會使用 unlink() 系統呼叫(參考18.3節)將
| 2016/10/30 | 初版 | Aaron Liao |
p125 | 微調 | 在倒數第六行:
原本是: 檔格式的中介資訊(meta-information)...
修改為: 檔格式的中繼資訊(meta-information)...
| 2016/11/04 | 初版 | Aaron Liao |
p126 | 微調 | 找到6.2節標題,在此段落的第3行:
原本是: (20.5節)接受呼叫者用指定的行程 ID 送出訊號給行程。...
修改為: (20.5節)接受呼叫者將訊號送給行程 ID 所代表的行程。...
| 2016/11/04 | 初版 | Aaron Liao |
p132 | 微調 | 在 6.4 節標題下方,第2行:
原本是: 因為了解虛擬記憶體有助於後續探討的主題,例如 fork() 系統呼叫、共用記憶體,
修改為: 因為了解虛擬記憶體有助於後續探討的主題,例如 fork() 系統呼叫、共享記憶體,
| 2016/11/04 | 初版 | Aaron Liao |
p149 | 微調 | 在第3行後方:
原本是: 程式會崩潰(crash)結束。然而,取決於堆疊的狀態,也可能會引起呼叫與傳回間的無窮呼叫返回迴圈,而程式好像真的從一個目前並未執行的函式中傳回了。
修改的地方: 程式會單純直接當掉(crash)而結束。然而,依據取決於堆疊的狀態,引起呼叫與傳回間的無窮呼叫返回迴圈,也可能會進入無窮的呼叫與返回循環,而程式的行為就好像真的從一個目前並未執行的函式中返傳回。
修改後的句子: 程式會單純直接當掉(crash)而結束。然而,依據堆疊的狀態,也可能會進入無窮的呼叫與返回循環,而程式的行為就像真的從一個目前並未執行的函式中返回。
| 2016/11/04 | 初版 | Aaron Liao |
p151 | 微調 | 找到中間的標題,在註解段落下方:
原本是: 盡可能避免使用 setjmp()函式和 longjmp() 函式
修改為: 盡可能避免使用 setjmp()函式和 longjmp() 函式 | 2016/11/04 | 初版 | Aaron Liao |
p151 | 微調 | 找到 6.9 節的標題,在此段落的第7行:
原本是: 程式呼叫時,命令列參數透過 argc 和 argv 參數提供給 main() 函式。通常, argv[0] 包含呼叫程式的名稱。
修改為: 在執行程式呼叫時,命令列參數是透過 argc 和 argv 參數提供給 main() 函式。通常, argv[0] 會包含呼叫程式的名稱。
| 2016/11/04 | 初版 | Aaron Liao |
p154 | 微調 | 在 brk()函式原型下方的第二段、第一行:
原本是: 想將 program break 設定為它的初始值底下(如:在&end底下)似乎會導致不可預期的行為,...
修改為: 想將 program break 設定為它的初始值以下(如:在&end以下)似乎會導致不可預期的行為,...
| 2016/12/03 | 初版 | Aaron Liao |
p155 | 微調 | 在 malloc 函式原型上方那兩行:
原本是: malloc()函式從堆積配置 size 個位元組(bytes)的記憶體,並傳回一個指向新配置記憶體區塊的指標,不會初始化所配置的記憶體。
修改為: malloc()函式從堆積配置 size 個位元組(bytes)的記憶體,並傳回一個指向新配置記憶體區塊的指標,不會對新配置的記憶體進行初始化。
| 2016/12/03 | 初版 | Aaron Liao |
p156 | 微調 | 此頁的第五行:
原本是: 可以最小化程式必須執行sbrk()呼叫的次數(如3.1節所提的,系統呼叫會有小但重要的負荷(overhead)。
修改的地方: 可以最小化將程式必須執行sbrk()呼叫的次數減到最少(如3.1節所述提的,系統呼叫會有小量但重要的負荷(overhead)會造成影響的負載)。
修改後的句子: 可以將程式必須執行sbrk()呼叫的次數減到最少(如3.1節所述,系統呼叫會有小量但會造成影響的負載)。 | 2016/12/03 | 初版 | Aaron Liao |
p164 | 微調 | 此頁標題【配置對齊的記憶體:memaligh()與posix_memaligh()】的下方:
原本是: memalign()與posix_memalign()函式可以從對齊指定的2次方邊界位址開始配置記憶體,對於一些應用程式是有用的功能(例如,參考列表13-1)。
修改為: 設計memalign()與posix_memalign()函式的目的是:可以從一個與2次方邊界對齊的位址開始配置記憶體,對一些應用程式而言是有用的功能(例如,參考列表13-1)。
| 2016/12/03 | 初版 | Aaron Liao |
p174 | 微調 | 找到中間的註解文字(字體較小),在此段落的第5行:
原本是: 念。)類似的同樣適用於 getgrnam() 和 getgrgid() 函式(稍後介紹)。
修改為: 念。)這同樣適用於 getgrnam() 和 getgrgid() 函式(稍後介紹)。
| 2016/11/04 | 初版 | Aaron Liao |
p175 | 訂正 | 找到標題【從群組檔檢索紀錄】的下方那一行:
原本是: 函式 getgrnam() 和 getgrgid() 的可從群組檔檢索紀錄。
修改為: 函式 getgrnam() 和 getgrgid() 的可從群組檔檢索紀錄。
| 2016/11/04 | 初版 | Aaron Liao |
p179 | 訂正 | 在 8.5 節的第9行:
原本是: 演算法,表示無法從加密過得密碼重新還原為原始的密碼。...
修改為: 演算法,表示無法從加密過的密碼重新還原為原始的密碼。...
| 2016/11/04 | 初版 | Aaron Liao |
p181 | 微調 | 修改使語意更清晰,在第三行:
原本是: ... 將已清除結尾的換行字元且以 NULL 結尾的輸入字串回傳。
修改的地方: ... 將傳回一個輸入字串,已清除此字串結尾的換行字元,並且以 NULL 結尾的輸入字串回傳。
修改後的句子: ... 將傳回一個輸入字串,已清除此字串結尾的換行字元,並且以 NULL 結尾。
| 2016/11/04 | 初版 | Aaron Liao |
p187 | 訂正 | 在此頁的第三段之第四行(不計程式碼)
原本是: 建立一個啟用set-userID(set-group-ID)的程式,用以將行程的有效使用者...
修改為: 建立一個啟用set-user-ID(set-group-ID)的程式,用以將行程的有效使用者...
| 2017/01/05 | 初版 | Aaron Liao |
p205 | 微調 | 在第二行:
原本是: 真實時間(real time):此時間的量測可源自:某個標準點(日曆時間)...
修改為: 真實時間(real time):此時間的量測起點可以是源自:某個標準點(日曆時間)...
| 2016/11/11 | 初版 | Aaron Liao |
p207 | 微調 | 在第一行:
原本是: 如果有提供 tz 參數,則會返回一個 timezone 結構,其欄位內容會包含 ...
修改為: 如果有提供 tz 參數,則會傳回一個 timezone 結構,其欄位內容會包含 ... | 2016/11/11 | 初版 | Aaron Liao |
p207 | 微調 | 在 time() 函式原型方框程式碼的下方第四行
原本是: timep 參數為無效位址時(EFAULT),所以我們通常會以下列的方式進行呼叫(不用錯誤檢查):
修改為: timep 參數為無效位址時(EFAULT),所以我們通常會以下列的方式進行呼叫(沒有進行錯誤檢查): | 2016/11/11 | 初版 | Aaron Liao |
p207 | 語意 | 在標題【 10.2 時間轉換函式】上方的那段註解,這段註解的倒數第二行:
原本是: gettimeofday() 系統呼叫。此時 time() 系統呼叫的存在就顯得冗贅,所以能以一個 gettimeofday() 函式庫函式來實作。
將紅字修改為藍字: gettimeofday() 系統呼叫。此時 time() 系統呼叫的存在就顯得冗贅,所以也可以將它實作成呼叫 gettimeofday() 的函式庫函式。 | 2016/11/11 | 初版 | Aaron Liao |
p208 | 微調 | 在標題【10.2.1】下方,位於 ctime 函式原型下方的第一行:
原本是: 將指向 time_t 值的指標以 timep 參數代入 ctime() 函式,...
修改為: 將指向 time_t 值的指標值做為以 timep 參數代入 ctime() 函式,...
在此頁的最後一個段落,在此段落的第一行:
原本是: 該字串包含一個結尾的換行符號及結尾的空位元組(null byte)。...
修改為: 該字串的結尾包含一個結尾的換行符號及一個結尾的空位元組(null byte)。...
在此頁的最後一行:
原本是: ... 傳回的字串是靜態配置的,之後呼叫 ctime() 時將會覆蓋它。
修改為: ... 傳回的字串是靜態配置的,之後再次呼叫 ctime() 時將會覆蓋這個字串內容。
| 2016/11/11 | 初版 | Aaron Liao |
p234 | 訂正 | 在本頁的第7行:
原本是: sysconf()、pathconf()及fpathconf(),供應用程式呼叫以檢查系統系統的限制和選項。
修改為: sysconf()、pathconf()及fpathconf(),供應用程式呼叫以檢查系統系統的限制和選項。
| 2016/11/13 | 初版 | Aaron Liao |
p234 | 語意 | 在 11.1 系統限制的第3段落(標楷體的小字註解)
原本是: 對於SUSv3定義的限制名稱,說這些包含_MAX字串名稱是最小值是挺令人困惑的。當我們了解這些用來定義某些資源或特性上限值的常數,標準的意思是,此上限值必須有明確的最小值時,這樣就能清楚理解了。 在某些情況,會將限制設定為最大值,而這些值的名稱包含了_MIN字串。這些常數所代表的意思是某些資源的下限,依標準所述,在符合標準的系統中,此下限不能大於某個值。例如,FLT_MIN(1E-37)這個限制的定義是,設定系統中能夠表示的最小浮點數之最大值,且全部遵循標準的系統至少都要能夠表示如此小的浮點數。
整段修改為: SUSv3所定義的一些限制命名會令人感到混淆,如有些內含_MAX字串的常數,但卻說這些常數是做為最小值用途。標準說資源限制的上限值需有一個最小值,即遵循標準的系統至少要能將該資源限制的上限設定為該常數。 相對地,有些內含_MIN字串的常數可用來指定一些資源或特定的下限。標準說資源限制的下限值不能大於某個特定值。遵循標準的系統至少要能將該資源限制的下限設定為該常數。以FLT_MIN(1E-37)限制為例,這個定義是設定系統所能表示的最小浮點數之最大值,表示遵循標準的系統至少要能設定到這麼小的最小浮點數。
| 2016/11/13 | 初版 | Aaron Liao |
p244 | 語意 | 在 11.6 節的第5行中間開始:
原本是: 此外,每個系統可以在編譯期聲明其實作的限制與選項(透過<limits.h>或<unistd.h>中的常數定義),且(或)在執行期(透過呼叫 sysconf()、pathconf()或fpathconf()函式)。
修改為: 此外,每個系統可以在編譯期與(或)在執行期聲明其實作的限制與選項(在編譯期是透過<limits.h>或<unistd.h>中的常數定義,而在執行期則是透過呼叫 sysconf()、pathconf()或fpathconf()函式)。
| 2016/11/13 | 初版 | Aaron Liao |
p262 | 微調 | 在此頁的倒數第八行:
原本是: ... 檔案的(硬性)連結數量、表示檔案最後存取時間、最後修改時間,...
修改一個字: ... 檔案的(硬式)連結數量、表示檔案最後存取時間、最後修改時間,...
| 2016/12/30 | 初版 | Aaron Liao |
p263 | 微調 | 在此頁中間 fsync() 函式原型上方的段落:
原本是: 系統呼叫 fsync()會將緩衝資料及開啟檔案描述符 fd 相關的全部中繼資料刷新到磁碟。
增加一個字: 系統呼叫 fsync()會將緩衝資料及開啟的檔案描述符 fd 相關的全部中繼資料刷新到磁碟。
在此頁的倒數第二行:
原本是: ...(我們提過檔案中繼資料的改變,如在同步I/O完整性完成狀態,不需要傳輸最後的修改時間。)...
修改為,增加兩個字: ...(我們提過檔案中繼資料的改變,如在同步I/O完整性資料完成狀態,不需要傳輸最後的修改時間。)...
| 2016/12/30 | 初版 | Aaron Liao |
p264 | 微調 | 在此頁下方的第一個小字註解段落:
原本是: 若修改過的核心緩衝區在30秒內未顯式同步到磁碟,則一個永久執行的核心執行緒會確保將已修改過的核心緩衝區刷新到磁碟中。此方法可確保緩衝區與其相對應的磁碟檔案不會長時間未同步(因而導致系統崩潰時資料遺失)。在Linux 2.6版本中,此任務由pdflush核心執行緒進行。(在Linux 2.4版本則由kupdated核心執行緒執行。)
修改為: 若修改過的核心緩衝區在30秒內未顯然地(explicitly)同步到磁碟,則一個永久執行的核心執行緒會確保將已修改過的核心緩衝區刷新到磁碟中。此方法可確保緩衝區與其相對應的磁碟檔案不會長時間未同步(因而導致系統崩潰時發生資料遺失)。在Linux 2.6版本中,此任務由pdflush核心執行緒進行。(在Linux 2.4版本則由kupdated核心執行緒執行。)
| 2016/12/30 | 初版 | Aaron Liao |
p266 | 微調 | 在此頁的倒數第三行:
原本是: 圖13-1左方所示的呼叫可在任何時間顯式強制刷新款衝區。
修改為: 圖13-1左方所示的呼叫可在任何時間顯然地強制刷新款衝區。 | 2016/12/30 | 初版 | Aaron Liao |
p312 | 更新 | 列表15-1的開頭:
原本是:
<#define _BSD_SOURCE /* Get major() and minor() from <sys/types.h> */
#include <sys/types.h>
#include <sys/stat.h> 將紅字修改為藍字:
#include <sys/sysmacros.h>
#include <sys/stat.h>
| 2016/10/19 | 初版 | man7.org |
p322 | 更新 | 在本頁的程式碼,最後一行:
原本是:
fatal("No group user (%s)", argv[1]); 修改為:
fatal("No group user (%s)", argv[2]);
| 2018/11/25 | 初版 | man7.org |
p348 | 更新 | 在本頁的程式碼,倒數第四行:
原本是:
printf("value=");
for (k = 0; k < valueLen; k++)
printf("%02x ", (unsigned int) value[k]); 修改為:
printf("value=");
for (k = 0; k < valueLen; k++)
printf("%02x ", (unsigned char) value[k]);
| 2018/11/23 | 初版 | man7.org |
p349 | 訂正 | 在標題【16.14小結】下方:
原本是: Linux從2.6版本之後,開始提供擴充屬性,以允許屬性中繼資料與檔案關聯,格式為一對的命名與值(name-value pair)。
修改為: Linux從2.6版本之後,開始提供擴充屬性,以允許任意的中繼資料與檔案關聯,格式為一對的命名與值(name-value pair)。
| 2016/12/10 | 初版 | Aaron Liao |
p397 | 更新
| 將此頁的部分列表18-3程式碼進行如下的修正:
原本是:
switch (sbuf->st_mode & S_IFMT) { /* Print file type */ case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFCHR: printf("c"); break; case S_IFBLK: printf("b"); break; case S_IFLNK: printf("l"); break; case S_IFIFO: printf("p"); break; case S_IFSOCK: printf("s"); break; default: printf("?"); break; /* Should never happen (on Linux) */ }
printf(" %s ", (type == FTW_D) ? "D " : (type == FTW_DNR) ? "DNR" : (type == FTW_DP) ? "DP " : (type == FTW_F) ? "F " : (type == FTW_SL) ? "SL " : (type == FTW_SLN) ? "SLN" : (type == FTW_NS) ? "NS " : " "); if (type != FTW_NS) printf("%7ld ", (long) sbuf->st_ino); else printf(" "); printf(" %*s", 4 * ftwb->level, ""); /* Indent suitably */ printf("%s\n", &pathname[ftwb->base]); /* Print basename */ return 0; /* Tell nftw() to continue */ }
修改為:
if (type == FTW_NS) { /* Could not stat() file */ printf("?"); } else { switch (sbuf->st_mode & S_IFMT) { /* Print file type */ case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFCHR: printf("c"); break; case S_IFBLK: printf("b"); break; case S_IFLNK: printf("l"); break; case S_IFIFO: printf("p"); break; case S_IFSOCK: printf("s"); break; default: printf("?"); break; /* Should never happen (on Linux) */ } }
printf(" %s ", (type == FTW_D) ? "D " : (type == FTW_DNR) ? "DNR" : (type == FTW_DP) ? "DP " : (type == FTW_F) ? "F " : (type == FTW_SL) ? "SL " : (type == FTW_SLN) ? "SLN" : (type == FTW_NS) ? "NS " : " "); if (type != FTW_NS) printf("%7ld ", (long) sbuf->st_ino); else printf(" "); printf(" %*s", 4 * ftwb->level, ""); /* Indent suitably */ printf("%s\n", &pathname[ftwb->base]); /* Print basename */ return 0; /* Tell nftw() to continue */ }
| 2018/02/14 | 初版 | man7.org |
p417 | 訂正
| 在表格 19-1:inotify 事件中,找到位元值下方第十行的位置,在 IN_MOVED_FROM 的下方新增一列 IN_MOVED_TO,內容如下:
新增的結果如下對應所示: 位元值 | IN | OUT
| 說明
| IN_MOVED_TO
| . | . | 將檔案移入所監看的目錄
|
| 2017/10/26 | 初版
| jim low |
p418 | 微調 | 在此頁的第六行:
原本是: OR運算後的結果。。
修改為 位元OR運算後的結果。。
在此頁的最後一行:
原本是: pathnames相關的監看描述符之「簿記,bookkeeping」資料結構)
修改為: pathname相關的監看描述符之「簿記,bookkeeping」資料結構)。
| 2016/11/15 | 初版 | Aaron Liao |
p420 | 微調 | 在第三段的第三行:
原本是: inotify_event 結構包含於 read() 傳回的緩衝區中,(參考圖19-2)。...
修改為: inotify_event 結構包含於 read() 傳回的緩衝區中,(參考圖19-2)。...
| 2016/11/15 | 初版 | Aaron Liao |
p420 | 語意 | 在第五段的第二行:
原本是: read() 中取得多個事件。read() 從 inotify 檔案描述符讀取事件的最小數量與所提供緩衝區中符合的事件數目。
修改的地方: read() 中取得多個事件。read() 從 inotify 檔案描述符讀取全部的事件數量,若緩衝區空間不足承載,則只會讀取緩衝區能容納的事件數量事件的最小數量與所提供緩衝區中符合的事件數目。
修改後的句子: read() 中取得多個事件。read() 從 inotify 檔案描述符讀取全部的事件數量,若緩衝區空間不足承載,則只會讀取緩衝區能容納的事件數量。
| 2016/11/15 | 初版 | Aaron Liao |
p423 | 訂正 | 在第三個段落(此頁中間)
原本是: 接著我們執行指令,在兩個目錄中產生事件,我們先使用用 cat(1) 建立檔案:
修正為: 接著我們執行指令,在兩個目錄中產生事件,我們先使用用 cat(1) 建立檔案:
| 2016/10/21 | 初版 | Aaron Liao |
p442 | 訂正 | 在此頁的第四行:
原本是: 不過我們在許多例程式中依然會在訊號處理常式中呼叫 printf(),...
增加一個字: 不過我們在許多範例程式中依然會在訊號處理常式中呼叫 printf(),...
| 2017/03/29 | 初版 | Aaron Liao |
p443 | 訂正 | 在此頁的倒數第九行:
原本是: 未規範將呼叫的行程排除在訊號的接收範圍之外,Linux 遵循是 BSD 系統的語意)。
修改為: 未規範將呼叫的行程排除在訊號的接收範圍之外,Linux 是遵循是 BSD 系統的語意)。
| 2017/03/29 | 初版 | Aaron Liao |
p444 | 訂正 | 在此頁的最後一行:
原本是: 另一個角度來看,表示我們可以使用空訊號來檢測指定行程 ID 的行程是否存在。
修改為: 另一個角度來看,表示我們可以使用空訊號來檢測指定的行程 ID 所代表的行程是否存在。
| 2017/03/29 | 初版 | Aaron Liao |
p459 | 微調 | 在此頁中間的結構型別,需要調整排版:
原本是:
struct sigaction { void (*sa_handler)(int); /* Address of handler */ sigset_t sa_mask; /* Signals blocked during handler invocation */ int sa_flags; /* Flags controlling handler invocation */ void (*sa_restorer)(void); /* Not for application use */ };
修改為:
struct sigaction { void (*sa_handler)(int); /* Address of handler */ sigset_t sa_mask; /* Signals blocked during handler invocation */ int sa_flags; /* Flags controlling handler invocation */ void (*sa_restorer)(void); /* Not for application use */ };
| 2017/03/29 | 初版 | Aaron Liao |
p459 | 訂正 | 此頁的倒數第三行:
原本是: 叫特地用途的 sigreturn() 系統呼叫,用以回存行程的執行內文 ...
修改為: 叫特定用途的 sigreturn() 系統呼叫,用以回存行程的執行內文 ...
| 2017/03/29 | 初版 | Aaron Liao |
p532 | 微調 | 此頁的倒數第三行:
原本是: 參數 new_value 的子結構 it_value 可指定計時器到期的延遲時間,...
修改為: 參數 new_value 的子結構 it_value 可指定計時器啟動之後與到期之間的倒數時間,...
| 2016/11/14 | 初版 | Aaron Liao |
p533 | 微調 | 在此頁的第一行中間開始:
原本是: ...,則在計時器每次的到期之後,就會將計時器重置,使得計時器可以在指定的間隔時間之後再次計時倒數。
修改為: ...,則在計時器每次的到期之後,就會依據間隔時間指定的時間值繼續重新倒數計時。
在此頁的倒數第六行中間:
原本是: ...,則會在計時器到期時重置。子結構 curr_value.it_interval ...
修改為: ...,則會在計時器到期之後將計時器重置。子結構 curr_value.it_interval ...
| 2016/11/14 | 初版 | Aaron Liao |
p537 | 微調 | 在此頁的標題【較簡單的計時器介面:alarm()】 標題下方的第二行:
原本是: 並且沒有重複的時間間隔(alarm() 以前原本就是設定計時器的 UNIX API。)。
修改為: 而沒有設定要指定重複計時的時間間隔欄位(alarm() 以前原本就是設定計時器的 UNIX API。)。
| 2016/11/14 | 初版 | Aaron Liao |
p538 | 訂正 | 一、將標題【23.3 計時器的排班與準確度】修改為【23.3 計時器的排班與精準度】
二、在標題 23.3 計時器的排班與準確度下方,第二段的第二行:
原本是: 計時器的準確(accuracy)往往是受限於軟體時鐘(software clock)的頻率 ...
修改為: 計時器的精準度(accuracy)往往是受限於軟體時鐘(software clock)的頻率 ... | 2017/03/13 | 初版 | Aaron Liao |
p540 | 語意 | 在頁面上方的程式碼以下的段落,第三行結尾到第四行開頭之處:
原本是: 因此不太常發生,不過這在實務上是可行的技術。
修改為: 因此不太可能發生,所以在實務上這項技術還是可行的。
| 2016/11/14 | 初版 | Aaron Liao |
p550 | 微調 | 在此頁下方 SIGEV_SIGNAL 旗標段落的第三行中間:
原本是: ... 此結構會傳遞給此訊號的處理常式、...
修改為: ... 此結構會被傳遞給此訊號的處理常式、...
| 2016/11/14 | 初版 | Aaron Liao |
p551 | 語意 | 在 SIGEV_THREAD_ID 旗標的段落中,第二行結尾的地方:
原本是: (在 SIGEV_SIGNAL 通知會讓訊號在該行程的佇列中排隊,而若行程中有多條執行緒時,則可將訊號傳遞給行程中的任一執行緒。請參考33.2節對執行緒互動及訊號的討論。)
修改為: (使用 SIGEV_SIGNAL 通知會讓訊號在該行程的佇列中排隊,而若行程中有多條執行緒時,則會隨意將訊號傳遞給行程中的任一執行緒。請參考33.2節對執行緒互動及訊號的討論。) 找到標題【23.6.2 啟動與停止計時器:timer_settime()】,在標題上方的那個段落:
原本是: 在目前的實作中,核心會為每個以timer_create()建立的POSIX計時器預先配置一個排隊中的即時訊號結構,預先配置的目的在於,確保在計時器到期時,至少有一個這樣的結構可供排隊中的訊號使用。這意謂著,可建立的POSIX計時器數量受限於可排隊的即時訊號數量(參考22.8節)。
修改的地方: 在目前的實作中,核心會為每個以timer_create()建立的POSIX計時器預先配置一個可排隊中的即時訊號結構,預先配置的目的在於,確保在計時器到期時,至少有一個這樣的結構可供排隊中的訊號排隊使用。這意謂著,可建立的POSIX計時器數量受限於可排隊的即時訊號的排隊空間數量(參考22.8節)。
修改後的內容: 在目前的實作中,核心會為每個以timer_create()建立的POSIX計時器預先配置一個可排隊的即時訊號結構,預先配置的目的在於,確保在計時器到期時,至少有一個這樣的結構可供訊號排隊。這意謂著,可建立的POSIX計時器數量受限於即時訊號的排隊空間(參考22.8節)。
| 2016/11/14 | 初版 | Aaron Liao |
p565 | 微調 | 在標題【範例程式】的上面那一行:
原本是: 時間到期了,則該檔案描述符表示為可讀。
修改為: 時間到期了,則該檔案描述符表示為(有資料)可讀。
| 2016/11/14 | 初版 | Aaron Liao |
p629 | 微調 | 在此頁的倒數第三段:
原本是: 函式execvp()和execlp()會在PATH包含的每個目錄中搜尋檔案,從清單開頭的目錄開始,直到成功執行了指定檔案。如果不清楚可執行程式的具體位置,或是不想因以程式寫死(hard-code)而對具體位置產生依賴,則可以利用PATH環境變數的方式。
修改的地方: 函式execvp()和execlp()會在PATH所列包含的每個目錄中搜尋檔案,從清單開頭的目錄開始,直到成功執行了指定的檔案為止。如果不清楚可執行程式的具體位置,或是不想因為在以程式碼中寫死(hard-code)執行檔位置而導致倚賴特定的執行路徑對具體位置產生依賴,則可以利用PATH環境變數的方式達成。
修改後的段落: 函式execvp()和execlp()會在PATH所列的每個目錄中搜尋檔案,從清單開頭的目錄開始,直到成功執行了指定的檔案為止。如果不清楚可執行程式的具體位置,或是不想因為在程式碼中寫死(hard-code)執行檔位置而導致倚賴特定的執行路徑,則可以利用PATH環境變數的方式達成。
| 2016/12/08 | 初版 | Aaron Liao |
p635 | 微調 | 在此頁的倒數第三段的第一行:
原本是: 由於awk會把字串longest_line.awk解釋為一個包含無效awk命令的腳本,因而execve()呼叫將以失敗告終。
修改為: 由於awk會把字串longest_line.awk解譯為一個包含無效awk指令的腳本,因而execve()呼叫會無法順利完成執行。
| 2017/01/02 | 初版 | Aaron Liao |
p643 | 微調 | 在此頁的最後一段:
原本是: 為了收集system()所建立的子行程狀態,以指定的子行程ID呼叫waitpid()。(使用wait()並不合適,因為wait()等待的是任一子行程,因而可能取得其他子行程的狀態。)列表27-8是system()的簡化實作。
修改的地方: 為了收集system()所建立的子行程狀態,我們使用以指定的子行程ID來呼叫waitpid()。(使用wait()並不合適,因為wait()等待的是任何一個子行程,因而可能取得其他子行程的狀態。),列表27-8是system()的簡化實作。
修改後的段落: 為了收集system()所建立的子行程狀態,我們使用指定的子行程ID來呼叫waitpid()(使用wait()並不合適,因為wait()等待的是任何一個子行程,因而可能取得其他子行程的狀態),列表27-8是system()的簡化實作。 | 2016/12/08 | 初版 | Aaron Liao |
p644 | 微調 | 在列表27-8下方標題之後的第一行:
原本是: 在system()實作的複雜度高,是因為要能正確地處理訊號。
首先需要討論的訊號是SIGCHLD。假設呼叫system()的程式也直接建立了其他子行程,對SIGCHLD的訊號處理常式自身也執行了wait()。
修改的地方:
在system()實作之所以的複雜度高,是因為要能正確地處理訊號。
首先需要討論的訊號是SIGCHLD。假設呼叫system()的程式也直接建立了其他子行程,並建立了對SIGCHLD的訊號處理常式,而且在處理常式中自身也執行了wait()。 修改後的段落: system()實作之所以複雜度高,是因為要能正確地處理訊號。
首先需要討論的訊號是SIGCHLD。假設呼叫system()的程式也直接建立了其他子行程,並建立了SIGCHLD的訊號處理常式,而且在處理常式中執行了wait()。
| 2016/12/08 | 初版 | Aaron Liao |
p647 | 更新 | 在本頁中間的那段小字體註解:
原本是: 一些system()實作反而會將子行程對SIGINT和SIGQUIT的處置重置為在呼叫者中生效的設定。這一做法的依據是,後續對execl()的呼叫會自動將對這些已處理訊號的處置重置為預設值。不過,如果呼叫者正在處理兩個訊號之一時,這可能會導致不預期的行為發生。在這種情況下,如果在呼叫execl()之前的瞬間有訊號送達子行程,那麼在訊號經由sigprocmask()解除阻塞後,子行程還是會呼叫訊號處理常式。
修改的地方: 一些system()實作反而會將子行程對SIGINT和SIGQUIT的處置重置為在呼叫者中生效的設定。這一做法的依據是,後續對execl()的呼叫會自動將對這些已處理訊號的處置重置為預設值。不過,如果呼叫者正在處理兩個訊號之一時,這可能會導致不預期的行為發生。在這種情況下,如果在呼叫execl()之前的瞬間有訊號送達子行程,那麼在訊號經由sigprocmask()解除阻塞後,則子行程還是會呼叫訊號處理常式。(相較之下,在列表27-9的實作中所展現的是,在execl()這個呼叫之前會有一個空窗期,在這段空窗期,這些訊號會受到忽略,而非依據呼叫者中生效的處置進行處理。)
修改後的段落:
一些system()實作反而會將子行程對SIGINT和SIGQUIT的處置重置為在呼叫者中生效的設定。這一做法的依據是,後續對execl()的呼叫會自動將對這些已處理訊號的處置重置為預設值。不過,如果呼叫者正在處理兩個訊號之一時,這可能會導致不預期的行為發生。在這種情況下,如果在呼叫execl()之前的瞬間有訊號送達子行程,則子行程還是會呼叫訊號處理常式。(相較之下,在列表27-9的實作中所展現的是,在execl()這個呼叫之前會有一個空窗期,在這段空窗期,這些訊號會受到忽略,而非依據呼叫者中生效的處置進行處理。)
| 2018/11/22 | 初版 | man7.org |
p662 | 訂正 | 此頁的第四個段落(小字的註解)
原本是: 堆疊的增長方向對架構的依賴是 clone() 設計的一處缺陷。Interl IA-64架構就提供了...
修正為: 堆疊的增長方向需取決於對架構的依賴是 clone() 設計的一處缺陷。Intel IA-64架構就提供了...
此頁的第五個段落,其中第二行
原本是: 的終止訊號(terminateion signal)...
修正為: 的終止訊號(termination signal)...
| 2016/10/19 | 初版 | Aaron Liao |
p663 | 微調 | 此頁的第一個段落,其中第二行開頭
原本是: 是在針對執行緒ID以及執行緒區域存放區的使用方面。...
修正為: 是在針對執行緒ID以及執行緒區域儲存空間 (thread-local storage) 的使用方面。...
| 2016/10/19 | 初版 | Aaron Liao |
p663 | 訂正 | 在此頁的範例程式標題下方,其中第二點
原本是: 若提供有命令列參數...
修正為: 若有提供有命令列參數...
| 2016/10/19 | 初版 | Aaron Liao |
p672 | 微調 | 在此頁的第二大標題【將子行程的行程 ID 設定為與父行程相同:CLONE_PID(已廢止) 】,此主題的倒數第二行:
原本是: 顆 CPU 建立隱身的空閒行程(idle process)...
修正為: 顆 CPU 建立隱身的閒置行程(idle process)...
| 2016/10/29 | 初版 | Aaron Liao |
p692 | 訂正 | 在此頁的倒數第四行(29.6節),將 pthred_exit() 修正為 pthread_exit()。
| 2017/03/02 | 初版 | 陳勁宇 |
p743 | 微調 | 在此頁的第一段:
原本是: 一般來說多個執行緒通常會平行執行,每個執行緒各自完成自己的任務,直到呼叫pthread_exit()終止執行緒,或是傳回到呼叫執行緒的函式。
調整的地方: 一般而言,來說多個執行緒通常會平行(parallel)執行,每個執行緒各自完成自己的任務,直到呼叫pthread_exit()終止執行緒為止,或是傳返回到呼叫執行緒的函式。
調整後的結果: 一般而言,多個執行緒通常會平行(parallel)執行,每個執行緒各自完成自己的任務,直到呼叫pthread_exit()終止執行緒為止,或是返回到呼叫執行緒的函式。 | 2017/01/02 | 初版 | Aaron Liao |
p749 | 訂正 | 在中間的函式原型下方的段落:
原本是: 執行緒呼叫函式pthread_cleanup_push()則將routine參數所指定的函式位址新增到清理處理常式堆疊,routine參數是一個函式指標格式如下:
修改為: 執行緒呼叫函式pthread_cleanup_push()則將routine參數所指定的函式位址新增到清理處理常式堆疊,routine參數是一個函式指標,其格式如下:
| 2017/01/02 | 初版 | Aaron Liao |
p750 | 訂正 | 在中間的【範例程式】標題下方的第四行:
原本是: ...,此處理常式在被時會傳入指定於 buf 中的地址做為參數。...
修改的地方: ...,此處理常式在被呼叫時會傳入指定於 buf 中的位地址做為參數。...
修改後的結果: ...,此處理常式在被呼叫時會傳入指定於 buf 中的位址做為參數。...
| 2017/01/02 | 初版 | Aaron Liao |