#ある整数が与えられて、それに相当するファイルディスクリプタが今のプロセスでオープンされてるかどうか、ってのを副作用なく調べる方法はあるか?
#dup呼ぶと副作用があるから後始末が面倒。
#lseekだとfdがパイプやソケットの場合に困る…いや困らないか。結果がEBADFかどうかだけ見ればいいのか。
#む、今のGaucheではinteger fdに対して直接lseekを呼ぶ方法がないかな。
#open-*-fd-portは内部でfdopenを呼ぶけど、これはfdが無効なものであっても成功する。
#ただそれで得られたportにport-tellを実行すると単に#fが帰って、これではunseekableだけどopenされてるポートと区別がつかない。
#やっぱり一時的にダミーのポートを開いて、そいつに向かってport-fd-dup!してみるしかないかな?
#Linux縛りでよければ、/proc/{自分のpid}/fd/{その整数} というファイルが存在するかどうか、というやり方もできますね。
#Linux の procfs はリッチすぎて、もはやprocfsとは呼べない気がする(笑)。
#ああそうか。しかし他のプラットフォームで別の手段に切り替えるのも面倒だな。
#ポータブルな方法となるとやっかいですね
#まあwindowsだとファイルディスクリプタによる操作ってのは馴染まないんでUnixファミリー限定の話ではあるんだけれど。
#*BSDでは、そもそも/procが一般的じゃなくて(あるけど)
#/proc にしても、Linuxのようにはリッチじゃないので、さきほどのやり方はほぼLinux縛りですね。
#なんでそんなことが必要になったかというと、(1)rfc.httpのhttpsサポートでstunnelを使うんだが、stunnel 4ではパラメータをextra file descriptor経由でパイプ作って渡す必要がある (2)じゃあrun-processを拡張してシェルみたいに自由にredirectionできるようにしよう (3)ついでだからシェルみたいに <& >& とかも使えるといいな (4)親プロセスからfd指定でdupする時に既にそのfdが開いてるかどうか知りたい、という流れ。
#なるほど
#Perlはどうやっているんだろう
#Perlのopen()って、そこいら辺の機能がてんこ盛りだった気が。
#あーでもfdは渡せないか
#現在のコードだとこんな感じで、fd=3にパイプ渡してます。
#(define (run-stunnel4 path)
(lambda (host:port)
(receive (in out) (sys-pipe)
(rlet1 p (run-process `(,path "-fd" 3)
:redirects `((< 0 stdin)
(> 1 stdout)
(> 2 :null)
(< 3 ,(port-file-number in)))
:wait #f)
(format out "client = yes\n")
(format out "connect = ~a" host:port)
(close-output-port out)))))
#たぶんこんなことする必要があるのってレアケースなんだけれど、出来ないとなると回避策が非常に面倒 (別にシェルスクリプト作って起動したりとか) なんだよね。
#ふむ...
#dup(2)しか思いつかないですね... なんかありそうな気がするんだけど。