Emacsにはネットワークをソケットとして操作するための機能が梱包されている。その中でも make-network-process
は基本となる関数の一つで、Cでネイティブに実装されている。今回は make-network-process
の使い方を確認する。
make-network-processはネットワークサーバーまたはクライアントプロセスを作成して返す。プロセスオブジェクトには入力と出力があり、通常のサブプロセスと同じように扱える。ただしネットワークプロセスにプロセスIDはなく、シグナルを送信できない。
ステータスコードは通常のものとは異なる。ここで言うプロセスとはOSの管理するプロセスではなく、Lisp_Process構造体のインスタンスと考えると良いかもしれない。Lisp_Processはプロセスのような挙動をするものを抽象化する構造体で、 make-process
でもこの構造体のインスタンスが生成される。typeというメンバーを持っており、通常のプロセス(OSの管理するプロセス)であればrealというシンボルが設定されている。ネットワークプロセスの場合はnetworkというシンボルが設定される。
UNIXドメインソケットのサーバー側ネットワークプロセス
make-network-process
を用いることで、低レベルな処理を行うことができる。ここではUNIXドメインソケットファイルを生成するサーバー側のネットワークプロセスを作成する。UNIXドメインソケットを利用するソケットのファミリーは、CではAF_UNIXを指定するが、Emacs Lispでは local
というシンボルを指定する。 :service
には作成するUNIXドメインソケットファイルへのパスを指定する。このパスにファイルが存在する場合、 make-network-process
は失敗する。
make-network-process
が成功すると、UNIXドメインソケットが生成される。そのUNIXドメインソケットに対し、接続しデータを送信することで通信できる。例としてPythonでの通信方法を示す。
import socket
soc = socket.socket(socket.AF_UNIX)
soc.connect("/tmp/foo.soc")
soc.send(b"TESTING")
soc.close()
ネットワークプロセスには :buffer
で指定したバッファがひもづいているが、接続を受けると新たにバッファとネットワークプロセスが作成される。通常親のプロセス名に <1>
や <2>
といった文字列が追加されたバッファ名となる。受信したデータはバッファに記述されるため、そのバッファを取得することでデータを取得できる。例えば次のようになる。
ネットワークプロセスを終了しソケットを閉じる場合 delete-process
を使用する。
このネットワークプロセスはdelete-processを用いて閉じる。ネットワークプロセスを作成するための情報はキーワード引数として渡す。
ソケットを閉じてもUNIXドメインソケットファイルは削除されない。
この当たりの実装は elnode
というサードパーティライブラリの実装が参考になるかもしれない。
引数の確認
make-network-process
は様々な引数を渡すことができる。docstringに説明が詳しく記載されているため、それを読むことで何を指定する必要があるのかを把握できる。
:name NAME – NAME is name for process. It is modified if necessary to make it unique.
:name NAME – NAMEにはプロセスの名前を指定する。プロセス名の変更は可能だが、 常にそのEmacs内で一意な値でなければならない。
:buffer BUFFER – BUFFER is the buffer (or buffer-name) to associate with the process. Process output goes at end of that buffer, unless you specify a filter function to handle the output. BUFFER may be also nil, meaning that this process is not associated with any buffer.
:buffer BUFFER – BUFFERは、プロセスに関連付けるバッファー(またはバッファー名)です。出 力を処理するフィルター関数を指定しない限り、プロセス出力はそのバッファー の最後に移動します。 BUFFERもnilの場合があります。これは、このプロセス がどのバッファーにも関連付けられていないことを意味します。
:host HOST – HOST is name of the host to connect to, or its IP address. The symbol `local' specifies the local host. If specified for a server process, it must be a valid name or address for the local host, and only clients connecting to that address will be accepted. If all interfaces should be bound, an address of \"0.0.0.0\" (for IPv4) or \"::\" (for IPv6) can be used. (On some operating systems, using \"::\" listens on both IPv4 and IPv6.) `local' will use IPv4 by default, use a FAMILY of `ipv6' to override this.
:host HOST – すべてのインターフェイスをバインドする必要がある場合は、 「0.0.0.0」(IPv4の場合)または「::」(IPv6の場合)のアドレスを使用で きます。 (一部のオペレーティングシステムでは、\ ":: \"を使用すると IPv4とIPv6の両方でリッスンします。) `local'はデフォルトでIPv4を使用し、 これをオーバーライドするには`ipv6'のFAMILYを使用します。HOSTは、接続す るホストの名前、またはそのIPアドレスです。記号`local'はローカルホスト を指定します。サーバープロセスに指定する場合は、ローカルホストの有効な 名前またはアドレスである必要があり、そのアドレスに接続しているクライア ントのみが受け入れられます。
:service SERVICE – SERVICE is name of the service desired, or an integer specifying a port number to connect to. If SERVICE is t, a random port number is selected for the server. A port number can be specified as an integer string, e.g., "80", as well as an integer.
:service SERVICE – SERVICEは、必要なサービスの名前、または接続するポー ト番号を指定する整数です。 SERVICEがtの場合、サーバーにはランダムなポー ト番号が選択されます。ポート番号は、整数だけでなく、「80」などの整数文 字列として指定できます。
:type TYPE – TYPE is the type of connection. The default (nil) is a stream type connection, `datagram' creates a datagram type connection, `seqpacket' creates a reliable datagram connection.
:type TYPE – TYPEは接続のタイプです。デフォルト(nil)はストリームタ イプの接続で、 `datagram'はデータグラムタイプの接続を作成し、 `seqpacket'は信頼できるデータグラム接続を作成します。
:family FAMILY – FAMILY is the address (and protocol) family for the service specified by HOST and SERVICE. The default (nil) is to use whatever address family (IPv4 or IPv6) that is defined for the host and port number specified by HOST and SERVICE. Other address families supported are: local – for a local (i.e. UNIX) address specified by SERVICE. ipv4 – use IPv4 address family only. ipv6 – use IPv6 address family only.
:family FAMILY – FAMILYは、HOSTおよびSERVICEによって指定されたサービ スのアドレス(およびプロトコル)ファミリーです。デフォルト(nil)は、 HOSTおよびSERVICEによって指定されたホストおよびポート番号に定義されて いるアドレスファミリ(IPv4またはIPv6)を使用することです。サポートされ ている他のアドレスファミリは次のとおりです。
- local – SERVICEによって指定されたローカル(つまりUNIX)アドレスの場合。
- ipv4 – IPv4アドレスファミリのみを使用してください。
- ipv6 – IPv6アドレスファミリのみを使用してください。
:local ADDRESS – ADDRESS is the local address used for the connection. This parameter is ignored when opening a client process. When specified for a server process, the FAMILY, HOST and SERVICE args are ignored.
:local ADDRESS – ADDRESSは、接続に使用されるローカルアドレスです。ク ライアントプロセスを開くとき、このパラメーターは無視されます。サーバー プロセスに指定されている場合、FAMILY、HOST、およびSERVICEの引数は無視 されます。
:remote ADDRESS – ADDRESS is the remote partner's address for the connection. This parameter is ignored when opening a stream server process. For a datagram server process, it specifies the initial setting of the remote datagram address. When specified for a client process, the FAMILY, HOST, and SERVICE args are ignored.
:remote ADDRESS – ADDRESSは、接続用のリモートパートナーのアドレスです。 ストリームサーバープロセスを開くとき、このパラメーターは無視されます。 データグラムサーバープロセスの場合、リモートデータグラムアドレスの初期 設定を指定します。クライアントプロセスに指定されている場合、FAMILY、 HOST、およびSERVICE引数は無視されます。
The format of ADDRESS depends on the address family:
- An IPv4 address is represented as a vector of integers [A B C D P]
corresponding to numeric IP address A.B.C.D and port number P.
- An IPv6 address has the same format as an IPv4 address but with 9
elements rather than 5.
- A local address is represented as a string with the address in the
local address space.
- An "unsupported family" address is represented by a cons (F . AV)
where F is the family number and AV is a vector containing the socket address data with one element per address data byte. Do not rely on this format in portable code, as it may depend on implementation defined constants, data sizes, and data structure alignment.
ADDRESSの形式は、アドレスファミリによって異なります。
- IPv4アドレスは、数値のIPアドレスA.B.C.Dとポート番号Pに対応する整数のベクトル[A B CDP]として表されます。
- IPv6アドレスの形式はIPv4アドレスと同じですが、5つではなく9つの要素があります。
- ローカルアドレスは、ローカルアドレススペース内のアドレスを含む文字列として表されます。
- 「サポートされていないファミリ」アドレスは、短所(F。AV)で表されます。 ここで、Fはファミリ番号であり、AVは、アドレスデータバイトごとに1つの要素を持つソケットアドレスデータを含むベクトルです。 実装で定義された定数、データサイズ、およびデータ構造の配置に依存する 可能性があるため、ポータブルコードではこの形式に依存しないでください。
:coding CODING – If CODING is a symbol, it specifies the coding system used for both reading and writing for this process. If CODING is a cons (DECODING . ENCODING), DECODING is used for reading, and ENCODING is used for writing.
:coding CODING – CODINGがシンボルの場合、このプロセスの読み取りと書き 込みの両方に使用されるコーディングシステムを指定します。 CODINGが短所 (DECODING。ENCODING)の場合、DECODINGは読み取りに使用され、ENCODINGは 書き込みに使用されます。
:nowait BOOL – If NOWAIT is non-nil for a stream type client process, return without waiting for the connection to complete; instead, the sentinel function will be called with second arg matching "open" (if successful) or "failed" when the connect completes. Default is to use a blocking connect (i.e. wait) for stream type connections.
:nowait BOOL – ストリームタイプのクライアントプロセスでNOWAITがnilで ない場合は、接続が完了するのを待たずに戻ります。代わりに、接続が完了す ると、「open」(成功した場合)または「failed」に一致する2番目の引数を 使用してセンチネル関数が呼び出されます。デフォルトでは、ストリームタイ プにブロッキング接続(つまり待機)を使用します。
:noquery BOOL – Query the user unless BOOL is non-nil, and process is running when Emacs is exited.
:noquery BOOL – BOOLがnil以外であり、Emacsが終了したときにプロセスが実行されていない限り、ユーザーにクエリを実行します。
:stop BOOL – Start process in the `stopped' state if BOOL non-nil. In the stopped state, a server process does not accept new connections, and a client process does not handle incoming traffic. The stopped state is cleared by `continue-process' and set by `stop-process'.
:stop BOOL – BOOLがnilでない場合、プロセスを「停止」状態で開始します。 停止状態では、サーバープロセスは新しい接続を受け入れず、クライアントプ ロセスは着信トラフィックを処理しません。停止状態は`continue-process'で クリアされ、`stop-process'で設定されます。
:filter FILTER – Install FILTER as the process filter.
:filter FILTER – プロセスフィルターとしてFILTERをインストールします。
:filter-multibyte BOOL – If BOOL is non-nil, strings given to the process filter are multibyte, otherwise they are unibyte. If this keyword is not specified, the strings are multibyte.
:filter-multibyte BOOL – BOOLがnil以外の場合、プロセスフィルターに指 定される文字列はマルチバイトです。それ以外の場合はユニバイトです。この キーワードが指定されていない場合、文字列はマルチバイトになります。
:sentinel SENTINEL – Install SENTINEL as the process sentinel.b
:sentinel SENTINEL – プロセスsentinel.bとしてSENTINELをインストールします。
:log LOG – Install LOG as the server process log function. This function is called when the server accepts a network connection from a client. The arguments are SERVER, CLIENT, and MESSAGE, where SERVER is the server process, CLIENT is the new process for the connection, and MESSAGE is a string.
:log LOG – サーバープロセスログ機能としてLOGをインストールします。こ の関数は、サーバーがクライアントからのネットワーク接続を受け入れるとき に呼び出されます。引数はSERVER、CLIENT、およびMESSAGEです。ここで、 SERVERはサーバープロセス、CLIENTは接続の新しいプロセス、MESSAGEは文字 列です。
:plist PLIST – Install PLIST as the new process's initial plist.
:plist PLIST – 新しいプロセスの初期plistとしてPLISTをインストールします。
:tls-parameters LIST – is a list that should be supplied if you're opening a TLS connection. The first element is the TLS type (either `gnutls-x509pki' or `gnutls-anon'), and the remaining elements should be a keyword list accepted by gnutls-boot (as returned by `gnutls-boot-parameters').
:tls-parameters LIST – TLS接続を開く場合に提供する必要のあるリストで す。最初の要素はTLSタイプ( `gnutls-x509pki'または`gnutls-anon')であ り、残りの要素はgnutls-bootによって受け入れられるキーワードリストであ る必要があります( `gnutls-boot-parameters'によって返されます)。
:server QLEN – if QLEN is non-nil, create a server process for the specified FAMILY, SERVICE, and connection type (stream or datagram). If QLEN is an integer, it is used as the max. length of the server's pending connection queue (also known as the backlog); the default queue length is 5. Default is to create a client process.
:server QLEN – QLENがnil以外の場合は、指定されたFAMILY、SERVICE、およ び接続タイプ(ストリームまたはデータグラム)のサーバープロセスを作成し ます。 QLENが整数の場合、最大値として使用されます。サーバーの保留中の 接続キューの長さ(バックログとも呼ばれます)。デフォルトのキューの長さ は5です。デフォルトでは、クライアントプロセスを作成します。
The following network options can be specified for this connection:
この接続には、次のネットワークオプションを指定できます。
:broadcast BOOL – Allow send and receive of datagram broadcasts. :dontroute BOOL – Only send to directly connected hosts. :keepalive BOOL – Send keep-alive messages on network stream. :linger BOOL or TIMEOUT – Send queued messages before closing. :oobinline BOOL – Place out-of-band data in receive data stream. :priority INT – Set protocol defined priority for sent packets. :reuseaddr BOOL – Allow reusing a recently used local address (this is allowed by default for a server process). :bindtodevice NAME – bind to interface NAME. Using this may require special privileges on some systems. :use-external-socket BOOL – Use any pre-allocated sockets that have been passed to Emacs. If Emacs wasn't passed a socket, this option is silently ignored.
:broadcast BOOL – データグラムブロードキャストの送受信を許可します。 :dontroute BOOL – 直接接続されたホストにのみ送信します。 :keepalive BOOL – ネットワークストリームでキープアライブメッセージを送信します。 :linger BOOL or TIMEOUT – 終了する前にキューに入れられたメッセージを送信します。 :oobinline BOOL – 帯域外データを受信データストリームに配置します。 :priority INT – 送信パケットのプロトコル定義の優先度を設定します。 :reuseaddr BOOL – 最近使用したローカルアドレスの再利用を許可する (これは、サーバープロセスではデフォルトで許可されています). :bindtodevice NAME – インターフェイスNAMEにバインドします。これを使用するには、一部のシステムで特別な特権が必要になる場合があります。 :use-external-socket BOOL – Emacsに渡された事前に割り当てられたソケットを使用します。 Emacsにソケットが渡されなかった場合、このオプションは黙って無視されます。
Consult the relevant system programmer's manual pages for more information on using these options.
これらのオプションの使用の詳細については、関連するシステムプログラマの マニュアルページを参照してください。
A server process will listen for and accept connections from clients. When a client connection is accepted, a new network process is created for the connection with the following parameters:
サーバープロセスは、クライアントからの接続をリッスンして受け入れます。 クライアント接続が受け入れられると、次のパラメータを使用して接続用の新 しいネットワークプロセスが作成されます。
- The client's process name is constructed by concatenating the server
process's NAME and a client identification string.
- If the FILTER argument is non-nil, the client process will not get a
separate process buffer; otherwise, the client's process buffer is a newly created buffer named after the server process's BUFFER name or process NAME concatenated with the client identification string.
- The connection type and the process filter and sentinel parameters are
inherited from the server process's TYPE, FILTER and SENTINEL.
- The client process's contact info is set according to the client's
addressing information (typically an IP address and a port number).
- The client process's plist is initialized from the server's plist.
- クライアントのプロセス名は、サーバープロセスのNAMEとクライアント識別文字列を連結することによって作成されます。
- FILTER引数がnil以外の場合、クライアントプロセスは個別のプロセスバッファを取得しません。それ以外の場合、クライアントのプロセスバッファは、サーバープロセスのBUFFER名またはクライアント識別文字列と連結されたプロセスNAMEにちなんで名付けられた新しく作成されたバッファです。
- 接続タイプとプロセスフィルターおよびセンチネルパラメーターは、サーバープロセスのTYPE、FILTER、およびSENTINELから継承されます。
- クライアントプロセスの連絡先情報は、クライアントのアドレス情報(通常はIPアドレスとポート番号)に従って設定されます。
- クライアントプロセスのplistは、サーバーのplistから初期化されます。
Notice that the FILTER and SENTINEL args are never used directly by the server process. Also, the BUFFER argument is not used directly by the server process, but via the optional :log function, accepted (and failed) connections may be logged in the server process's buffer.
FILTERおよびSENTINEL引数がサーバープロセスによって直接使用されることは ないことに注意してください。また、BUFFER引数はサーバープロセスによって 直接使用されませんが、オプションの:log関数を介して、受け入れられた (および失敗した)接続がサーバープロセスのバッファーに記録される場合が あります。
The original argument list, modified with the actual connection information, is available via the `process-contact' function.
実際の接続情報で変更された元の引数リストは、`process-contact'関数を介して利用できます。
usage: (make-network-process &rest ARGS)