8

In inetd and systemd type systems, it is possible for the system to bind a socket and launch the application with the socket already existing, for example to provide socket based service starting. I would like to take advantage of this functionality in one of my Haskell daemons.

The daemon currently calls, socket, bindSocket, listen to create a Socket object that I can later call accept on. To change this to an inetd type system I would need to use standard input as a Socket, but all I can find so far is stdin :: Handle, or fdToHandle :: CInt -> Handle - neither are quite what I need.

I can't seem to find anything that has type Handle -> Socket, nor anything that is like stdin :: Socket. The nearest I can find is mkSocket which is very low-level, and most other languages (ie, Ruby) provide a call to turn a file descriptor into a socket without having to specify various other parameters.

4

2 に答える 2

4

sd-daemon.hC アプリケーションには、ソケットの受け渡しを自動的に処理する which を持つという贅沢があります。Haskell では、このファイルを手動でエミュレートする必要があります。

ファイル記述子stdInputを取得するために使用できます。機能ももちろん使えますstdinhandleToFdただし、POSIX 固有の動作が必要なため、Windows で動作することは期待できません。

FDを手に入れたら、mkSocket機能を使うしかありません。Haskell は、必要なソケットの種類を推測できないため、指定する必要があります。あなたはおそらく欲しい:

mkSocket fd AF_UNIX Stream defaultProtocol Listening

これは必ずしもsystemdファイル記述子をアプリケーションに渡す方法ではないことに注意してください。LISTEN_FDSおよび環境変数をチェックしてLISTEN_PID、使用するファイル記述子を確認し、ソケットをバインドする必要があるかどうかを確認する必要があります。デフォルトのソケットを表すデフォルトのファイル記述子は、想定している FD 0 ではなく、FD 3 です。systemdまた、サービス ファイルで要求された場合に使用する複数のソケットを提供する場合もあります。

于 2012-07-19T11:15:32.210 に答える
1

MkSocket の主な秘訣は、適切なパラメーターがあることを知ることです。sd-daemon.h がこれに役立ちます。sd_is_fifo の systemd man ページから、fstat と getsockname を使用していることがわかります。sd_is_socket のコードは git here にあります

unix パッケージfstatに包まれたものを使用して支援することができます

getFdStatus :: Fd -> IO FileStatus

isSocket :: FileStatus -> Bool

Network パッケージ (部分的に Network.Socket.Internals を使用) も Cgetsockname関数を使用します (ヘルパーwithNewSockAddrは応答に適切なバッファーを割り当てます)。これには、「ファミリ」を推測するか、おそらく回答用に大きなバッファを割り当てる必要があります ( sockaddr_storageRFC 2553 から)。ただし、ネットワークはデータからソケット ファイル記述子を取得しSocketます。Network からコードを取り出して、sd-daemons.h が行うチェックを再実装することができます。

また、getsockoptコードはおそらくnetwork-socket-options パッケージにラップされています。

しかし、誰もあなたが必要とする方法でそれをまとめたようには見えません。奇数。

于 2012-07-19T12:54:17.290 に答える