Mac OS X Lion 的 Sandbox 模式與輸入法

這篇文字想來對絕大多數人都沒什麼用處,不過就是自己留一篇筆記。

把工作機升級到 Mac OS X Lion 之後,在一些應用程式當中,例如系統內建的文字編輯工具(TextEdit.app)以及預覽程式(Preview)中,就遇到無法使用輸入法的問題—點選輸入法選單,我要用的輸入法選項就是灰色的,無法選用。說起來奇怪,應該不是輸入法程式本身有什麼問題,因為在其他應用程式中可以正常使用,而且之前在測試 Beta 版本的 Lion 時,也沒有遇到這個問題,用搜尋引擎找個一輪,也沒有看到其他人遇到這種狀況。

不過,既然是 Mac OS X,遇到什麼錯誤,打開 Console,總是可以撈到些訊息,找到點線索。果然,Console 裡頭看到這樣的記錄:

7/21/11 6:36:45.986 PM sandboxd: ([11590]) TextEdit(11590) deny file-read-data /Users/zonble/Work/MyInputMethod/build/Debug/MyInputMethod.app

從訊息看起來,是被 Lion 的新功能—sandbox 模式—擋住了,另外還有一份完整的 backtrace。而之所以 TextEdit 與 Preview 不能使用,而其他應用程式可以使用,就在於,目前絕大多數程式都還沒有包在 sandbox 裡頭,但是這兩套卻已經使用了 sandbox 模式;在 Lion 上面,現在可以使用 Activity Monitor,查看目前正在執行的程式,到底有沒有使用 sandbox。

講一下 Lion 的 sandbox 模式。

簡單來說,蘋果認為要能夠保障系統安全,目前許多作業系統使用 UI 警告使用者的這種作法是有問題的:目前許多作業系統中,執行新的應用程式的時候,都一直跳出對話框警告這個程式可能有安全性問題,到底要不要執行…這麼做不過是將系統安全的責任推給使用者,只要使用者按下確定,系統就不用負擔責任。但這麼一來,系統安全問題還是會繼續發生,而且這樣的 UI 非常惱人。於是,蘋果認為,不如一開始就限制各種應用程式可以做的事情,在 Lion 中加入 sandbox 設計。

於是,接下來一套應用程式如果想要在 Mac AppStore 上架,就要包含一個 Entitlement 檔案,Entitlement 還要加上 Code Signing,裡頭宣告會用到哪些權限,包括是否可以存取檔案、是否可以使用網路連線…等。而就算有了讀取檔案的權限,除了使用標準的檔案對話框元件( NSSavePanel 與 NSOpenPanel)外,在使用者可以看到的狀況下存取檔案外,就只能夠讀取一定範圍的檔案,將這套程式能夠讀取資料的範圍,與系統的其他部分隔絕開來。

雖然還有許多程式還沒有使用 sandbox 模式,但蘋果要確保至少在 AppStore 上販賣的軟體沒有問題。而且,也看不出來蘋果打算從什麼時候開始強制要求,畢竟現在 Mac AppStore 還是要繼續支援 Snow Leopard 一陣子。

但這麼說起來,讓人實在看不出來跟輸入法之間有什麼關係—在 Input Method Kit 的架構下,輸入法軟體(Input Server)與正在使用輸入法打字的軟體(Input Client)之間,是使用 Distribuited Object 做 IPC,為什麼 Input Client 會去讀 Input Server 的目錄內容?而且為什麼會無法讀取?

盯著 Backtrace Log,來來回回搞了一陣,終於搞清楚狀況。一套軟體要知道有哪些輸入法可以用,會去呼叫 Text Input Source Services 這部份的 API,TIS API 會透過讀取輸入法程式的 Application Bundle 內的資訊(就是 Info.plist 啦), 知道這套輸入法叫什麼名字、要用什麼圖示等等。這也就代表,各個應用程式都應該要有讀取輸入法程式 bundle 內容的能力,就算是處在 sandbox 模式,也應該要有讀取輸入法安裝目錄(/Library/Input Methods/、 ~/Library/Input Methods/ 等)的權限。

所以,回頭看看上面的錯誤訊息,有沒有看出什麼?

7/21/11 6:36:45.986 PM sandboxd: ([11590]) TextEdit(11590) deny file-read-data /Users/zonble/Work/MyInputMethod/build/Debug/MyInputMethod.app

沒錯,我的輸入法程式的 Application Bundle,根本就沒放在用來安裝輸入法的目錄裡頭,因為我在用的輸入法是直接從程式碼編譯出來的,而且之前經常改來改去,所以就直接把 build 目錄底下的 debug 版本,透過 symbolic link 的方式,連到 ~/Library/Input Methods/ 底下,這樣每次重新編譯,就只要把輸入法的 process 給 kill 掉就好,不必每次都將新版的程式複製一次。結果呢,就是要使用輸入法的應用程式雖然可以讀取輸入法安裝目錄,但是並沒有讀取 symbolic link 過去的目錄的全縣。

也難怪在網路上也查不到其他人遇到這個狀況,想來也沒有多少人會這樣安裝輸入法嘛。

2 thoughts on “Mac OS X Lion 的 Sandbox 模式與輸入法

  1. 您好,

    Sorry, 我找不到您的e-mail, 所以用了連結的blog. TCfail這個軟體真的很實用,但是我想問一下是否可以放大自體,因為我的27吋iMAC變粗仍不夠,希望可以變大,不知是否有相關的程式或方法可以指教,謝謝您!

    找了很久才找到此軟體的Linda

  2. Pingback: 【转】Mac OS X Lion 的 Sandbox 模式与输入法 - iOS - 开发者问答

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.