Next: , Previous: , Up: Processes   [Contents][Index]


36.4 非同期プロセスの作成

このセクションでは非同期プロセス(asynchronous process)を作成する方法について説明します。非同期プロセスは作成後はEmacsと並列に実行されて、Emacsは以降のセクション(Input to ProcessesOutput from Processesを参照)で説明する関数を使用してプロセスとコミュニケーションができます。プロセスコミュニケーションは部分的に非同期なだけであることに注意してください。Emacsは特定の関数を呼び出したときだけプロセスにデータを送信でき、Emacsは入力の待機中か一定の遅延時間の後にのみプロセスのデータを受け取ることができます。

非同期プロセスはpty(pseudo-terminal: 疑似端末)かたはpipeのいずれかを通じて制御されます。ptyかpipeの選択は、デフォルトでは変数process-connection-type (以下参照)の値にもとづいてプロセス作成時に行われます。ptyが利用可能なら、通常はShellモード内のようにユーザーから可視なプロセスに適しています。ptyではプロセスとその子プロセスとの間でジョブ制御(C-cC-z、...等)が可能であり、対話的なプログラムはptyを端末デバイスとして扱いますが、これらはpipeではサポートされない機能だからです。Lispプログラムの内部的な目的のために使用されるサブプロセスにたいしては、pipeのほうが適している場合が多々あります。それはpipeがより効率的であり、ptyが大量の文字(500byte前後)にたいして導入する迷入文字インジェクション(stray character injections)にたいして免疫があるのが理由です。さらに多くのシステムではptyの合計数に制限があり、それを浪費するのは得策ではありません。

Function: make-process &rest args

この関数は非同期サブプロセスを開始するための基本的な低レベルなプリミティブである。これはサブプロセスを表すプロセスオブジェクトをリターンする。以下で説明するより高レベルなstart-processと比較すると、この関数はキーワード引数を受け取り、より柔軟であり、単独の呼び出しでプロセスフィルターやセンチネルを指定できる。

引数argsはkeyword/argumentペアのリスト。キーワードの省略は値nilでそれを指定することと常に等価。以下は意味のあるキーワード:

:name name

プロセス名として文字列nameを使用する。その名前のプロセスがすでに存在すれば、(‘<1>’、...の追加により)一意となるようにnameを修正する。

:buffer buffer

プロセスバッファーとしてbufferを使用する。値がnilなら、そのサブプロセスには何のバッファーも関連付けられない。

:command command

プロセスのコマドラインとしてcommandを使用する。値はプログラムの実行可能ファイル名で始まり、後にプログラムの引数として与える文字列が続くリストであること。リストの最初の要素がnilなら、Emacsは新たな擬似端末(pty)を作成して、実際には何もプログラムを実行せずに入出力をbufferに関連付ける。この場合には残りのリスト要素は無視される。

:coding coding

codingがシンボルなら、それはその接続にたいする読み取りと書き込みの両方で使用するコーディングシステムを指定する。codingがコンスセル(decoding . encoding)なら読み取りにdecoding、書き込みにencodingが使用される。プログラムに書き込むデータのエンコーディングに使用されるコーディングシステムは、コマンドライン引数のエンコーディングにも使用される(しかしプログラム自身にたいしてファイル名を別のファイル名にエンコードすることはない。file-name-coding-systemを参照)。

codingnilなら、デフォルトのコーディングシステム検出ルールを適用する。Default Coding Systemsを参照のこと。

:connection-type TYPE

サブプロセスとの対話に使用するデバイスのタイプを初期化する。指定できる値はptyを使用するpty、pipeを使用するpipe、またはprocess-connection-type変数の値のデフォルトデバイスを使用するnil:stderrパラメーターに非nil値が指定されると、このパラメーターとprocess-connection-typeの値は無視される。この場合にはタイプは常にpipeになる。

:noquery query-flag

プロセスqueryフラグをquery-flagに初期化する。Query Before Exitを参照のこと。

:stop stopped

stoppedが非nilなら、停止状態でプロセスを開始する。

:filter filter

プロセスフィルターをfilterに初期化する。未指定ならデフォルトフィルターが提供されるが、これは後からオーバーライドできる。Filter Functionsを参照のこと。

:sentinel sentinel

プロセスセンチネルをsentinelに初期化する。未指定ならデフォルトセンチネルが使用されるが、これは後からオーバーライドできる。Sentinelsを参照のこと。

:stderr stderr

プロセスの標準エラーにstderrを割り当てる。値が非nilならバッファー、または以下で説明するmake-pipe-processで作成されたpipeのいずれかであること。

実際の接続情報で修正されたオリジナルの引数リストはprocess-contactを通じて利用できる。

Function: make-pipe-process &rest args

この関数は子プロセスにアタッチ可能な双方向のpipeを作成する。これはmake-process:stderrキーワードと併用することで有用。この関数はプロセスオブジェクトをリターンする。

引数argsはkeyword/argumentペアのリスト。キーワードの省略はそのキーワードに値nilを指定することと常に等価。

以下は意味のあるキーワード。

:name name

プロセス名として文字列nameを使用する。make-processの場合のように、一意にするために必要に応じて変更され得る。

:buffer buffer

プロセスバッファーとしてbufferを使用する。

:coding coding

codingがシンボルなら、それはその接続にたいする読み取りと書き込みの両方で使用するコーディングシステムを指定する。codingがコンスセル(decoding . encoding)なら読み取りにdecoding、書き込みにencodingが使用される。

codingnilなら、デフォルトのコーディングシステム検出ルールを適用する。Default Coding Systemsを参照のこと。

:noquery query-flag

プロセスqueryフラグをquery-flagに初期化する。Query Before Exitを参照のこと。

:stop stopped

stoppedが非nilなら、停止状態でプロセスを開始する。

:filter filter

プロセスフィルターをfilterに初期化する。未指定ならデフォルトフィルターが提供されるが後で変更できる。Filter Functionsを参照のこと。

:sentinel sentinel

プロセスセンチネルをsentinelに初期化する。未指定ならデフォルトセンチネルが使用されるが後で変更できる。Sentinelsを参照のこと。

実際の接続情報で修正されたオリジナルの引数リストはprocess-contactを通じて利用できる。

Function: start-process name buffer-or-name program &rest args

この関数はcall-processの類似したインターフェースを提供する、make-process周辺の高レベルのラッパー。これは新たに非同期サブプロセスを作成して、指定されたprogramの実行をその内部で開始する。これはLispで新たなサブプロセスを意味するプロセスオブジェクトをリターンする。引数nameはプロセスオブジェクトの名前を指定する。make-processの場合のように、一意な名前となるように必要に応じて修正する。バッファーbuffer-or-nameはそのプロセスに関連付けるバッファー。

programnilならEmacsは疑似端末(pty)を新たにオープンして、サブプロセスを新たに作成することなくptyの入力と出力をbuffer-or-nameに関連付ける。この場合には残りの引数argsは無視される。

残りのargsはサブプロセスにコマンドライン引数を指定する文字列。

以下の例では1つ目のプロセスを開始して100秒間実行(というよりはsleep)される。その間に2つ目のプロセスを開始して、一意性を保つために‘my-process<1>’という名前が与えられる。これは1つ目のプロセスが終了する前にバッファー‘foo’の最後にディレクトリーのリストを挿入する。その後に2つ目のプロセスは終了して、その旨のメッセージがバッファーに挿入される。さらに遅れて1つ目のプロセスが終了して、バッファーに別のメッセージが挿入される。

(start-process "my-process" "foo" "sleep" "100")
     ⇒ #<process my-process>

(start-process "my-process" "foo" "ls" "-l" "/bin")
     ⇒ #<process my-process<1>>

---------- Buffer: foo ----------
total 8336
-rwxr-xr-x 1 root root 971384 Mar 30 10:14 bash
-rwxr-xr-x 1 root root 146920 Jul  5  2011 bsd-csh
…
-rwxr-xr-x 1 root root 696880 Feb 28 15:55 zsh4

Process my-process<1> finished

Process my-process finished
---------- Buffer: foo ----------
Function: start-file-process name buffer-or-name program &rest args

start-processと同じようにこの関数は非同期サブプロセスを開始して、その内部でprogramを実行してそのプロセスオブジェクトをリターンする。

start-processとの違いは、この関数がdefault-directoryの値にもとづいてファイルハンドラーを呼び出すかもしれないという点である。このハンドラーはローカルホスト上、あるいはdefault-directoryに応じたリモートホスト上でprogramを実行すること。後者の場合には、default-directoryのローカル部分はそのプロセスのワーキングディレクトリーになる。

この関数はprogram、またはargsの残りにたいしてファイル名ハンドラーの呼び出しを試みない。

そのファイルハンドラーの実装によっては、リターン結果のプロセスオブジェクトにprocess-filterprocess-sentinelを適用することができないかもしれない。Filter FunctionsSentinelsを参照のこと。

いくつかのファイルハンドラーはstart-file-processをサポートしないかもしれない(たとえばange-ftp-hook-function関数)。そのような場合には、この関数は何も行わずにnilをリターンする。

Function: start-process-shell-command name buffer-or-name command

この関数はstart-processと同様だが、指定されたcommandの実行にshellを使用する点が異なる。引数commandはshellコマンド文字列。変数shell-file-nameはどのshellを使用するかを指定する。

make-processstart-processでプログラムを実行せずにshellを通じて実行することの要点は、引数内のワイルドカード展開のようなshell機能を利用可能にするためである。そのためにはコマンド内に任意のユーザー指定引数を含めるなら、任意の特別なshell文字がshellでの特別な意味をもたないように、まずshell-quote-argumentでそれらをクォートするべきである。Shell Argumentsを参照のこと。ユーザー入力にもとづいたコマンド実行時には当然セキュリティ上の影響も考慮するべきである。

Function: start-file-process-shell-command name buffer-or-name command

この関数はstart-process-shell-commandと似ているが、内部的にstart-file-processを使用する点が異なる。これによりdefault-directoryに応じてリモートホスト上でもcommandを実行できる。

Variable: process-connection-type

この変数は非同期サブプロセスと対話するために使用するデバイスタイプを制御する。これが非nilの場合には利用可能ならpty、それ以外ならpipeが使用される。

process-connection-typeの値はmake-processstart-processの呼び出し時に効果を発揮する。そのためにこれらの関数の呼び出し前後でこの変数をバインドすることにより、サブプロセスとやり取りする方法を指定できる。

この変数の値はmake-processが非nil値の:stderrパラメーターで呼び出された際には無視される。この場合には、Emacsはpipeを使用してプロセスと対話する。

(let ((process-connection-type nil))  ; pipeを使用
  (start-process …))

与えられたサブプロセスが実際にはpipeとptyのどちらを取得したかを判断するには関数process-tty-nameを使用する(Process Informationを参照)。


Next: , Previous: , Up: Processes   [Contents][Index]