2011-06-20 19 views
3

ptyマスター/スレーブペアにファイル記述子のペアを使用するライブラリ(libvte、ターミナルエミュレーションライブラリ)があります。私は自分の使用のためにライブラリからマスターfdを "盗む"ことができなければなりません。(まれに、ZMODEMのサポートを実装するために、 'ネットは端末経由でしかありません。しかし、問題があります。POSIXシステムでのファイル記述子の終了を防止する

libvteに、ファイル記述子を新しいものに変更したいと言うことができますが、使用しているマスターを閉じて、代わりに新しいものを使用しようとします。マスターが閉じたときにスレーブが遠ざかり、これは機能しません。もともと私はをpty masterに使うことができると思っていたので、libvteがPTYマスター上でclose()を実行したときに、まだ機能するfdを使用していました。それは明らかに間違っています。 FDの

  • ブロックlibvteのread()事業:

    は、私はどちらかへの道を見つける必要があります。

  • は盗む
  • FD離れlibvteから、私はそれを使ってやっている時まで(例えば、私は出口にそれを接続していrzプロセスまで)

は、これらのもののいずれかを実行するためにPOSIXシステム上のことが可能です?あるいはlibvte自体にパッチを当てることなく同じことを達成するための他の方法がありますか?私が尋ねる理由は、ソリューションがかなりの数の既存のシステムで動作しなければならないということです。

私はlibvte(とGTK +自身)とPythonでインタフェースしています。しかし、私はPython拡張モジュールを読み込むためにシステムに特権を持つ必要はないので、Python拡張モジュールをC言語でPythonプログラムから呼び出すことはできません。

私はlibvteをforkして自分のやりたいことをやりたいのですが、私のプログラムでそれを配布してもよいでしょう。フォークを維持して立ち往生してください!

+0

Pythonでタグ付けしたくない、またはCですか?がんばろう! – shellter

+0

私は、質問は本当に両方には不可知論的だと思います。もし私が "C"にタグを付けると、それは本当にCの質問ではないと言えるでしょう。それはPythonの質問です); Pythonにタグを付けると、実際にはCレベルまたはシステムコールレベルの問題であると言えるでしょう。 –

+0

「自分の」専門分野を言語でチェックする人には、あなたの質問は決して見られないかもしれません。私はPOSIXの基本的な言語(ほぼ確実)なので、私は 'C'と一緒に行くだろう。 'ファイル記述子'と比較していますか? ;-)?答えが得られない場合は、いつでもPythonに変更することができます。私は私の標準的な '小切手S.O.'に 'C'あいまいな質問で私が見る回答の強さは謙虚である;-)幸運! – shellter

答えて

3

一つの可能​​な解決策独自のptyマスタ/スレーブペアを開き、libvteとスレーブPTY上で動作する実際のターゲットプログラムの間に介在ヘルパープロセスの書き込みを次のようになります。

+---------------+ 
| libvte  | 
|    | 
| pty master=|-----\ 
+---------------+  | 
         | 
+---------------+  | 
| helper proxy |  | 
|    |  | 
| stdin/stdout=|-----/ 
|    | 
| pty master=|-----\ 
+---------------+  | 
         | 
+---------------+  | 
| target  |  | 
|    |  | 
| stdin/stdout=|-----/ 
+---------------+ 

あなたのヘルパープロセスをZMODEMトラフィックを見るまで通常はデータを通過します。その後、stdin/stdout(それはlibvteになる)にデータを渡すことを停止し、別のファイルディスクリプタを使ってアプリケーションに渡すか、それとも単にrzを呼び出します。

1

dup() 'ファイル記述子は、close()他のインスタンスの呼び出しによって影響を受けません。しかし、libvteが状態を変更する他のシャットダウンメソッドを呼び出す可能性があります。詳しくは、straceをご利用ください。

あなたができることはいくつかありますが、どれもきれいではありません。 1つのオプションは、libvteの下のファイル記述子を置き換えることです。それは次のとおりです。

  • まず、FDのあなた自身のコピーを入手し、あなた自身の選択の一つでlibvteのFDを上書きするためにどこか
  • 使用dup2()それを隠しておくdup()を使用しています。これはlibvteの混乱を避けるために、あなたが盗んだものと似た構成の新しいptyでなければなりません。あなたはもう一方の端に何も書き込まないので、読み込みがブロックされます(libvteがそこに書き込む可能性のあるデータで何かをする必要があります)。
  • libvteがその時点でブロックread()にある場合は、 read()呼び出しを中断するためにスレッド(no-op-ではなく、 SIGIGN-ハンドラ)にシグナルを送ります。
  • 任意のPTY状態の変化がlibvteコピーし、正常な状態に戻るFD戻すためにdup2()を使用するには、スタート
  • で複製さfdにあなたの仕事を、元の記述子に行われている可能性があります。

また、cafが示唆しているように、最初からプロキシーptyを持っていればよいのです。

関連する問題