13

シリアル デバイス (/dev/ttyXX) から複数のプロセスを読み取ると、両方のプロセスがすべてのデータを取得できなくなります。データは何らかの方法でプロセス間で分割されます。シリアル デバイスから読み取り、いくつかのマスター/スレーブ pty ペアを作成し、シリアル デバイスから読み取るように作成されたプログラムが代わりに pty から読み取れるようにして、すべての読み取りプロセスがデータを受信できるようにするプログラムを作成したいと考えています。 pty から読み取りを開始すると、最新のデータのみを取得するという意味で、pty はシリアル デバイスのように動作します。つまり、読み取りを開始する前に書き込まれたデータは取得されません (これが /dev/ttyXX デバイス、または少なくとも私が読み取っている RS-232 風速計の動作方法であるというのが私の経験です)。名前付きパイプは、SIGPIPE をトラップしてリーダーがないと判断することで、これらのセマンティクスを模倣できるため、その特定の名前付きパイプに書き込みを行わないように選択できます。ただし、ターミナルを使用するように作成された一部のバイナリは、名前付きパイプと通信するときに失敗する可能性があります。ここで重要なのは、端末用に作成された既存のバイナリを使用できるようにすることです。

したがって、pty のスレーブ側が読み取り用に開かれていることを検出できれば、名前付きパイプの場合に SIGPIPE がない場合とほぼ同じセマンティクスが得られるはずです。HP-UX には ioctl() コマンドとして TIOCTRAP があり、これはまさに私が望んでいることを実行しているように見えますが、残念ながら Linux では利用できません。

私は何日も参考文献を読んできましたが、この種のオプションの数は驚異的です。答えは、端末の設定、ブロック/非ブロック動作、どこかにバッファ サイズを設定すること、poll()/select() から報告される条件、またはいくつかの組み合わせにある可能性があります。しかし、私は何も見つけられないようです。独自のデバイスドライバーを作成する必要がある可能性があるかどうか疑問に思っていますが、そこまで行かなくてもこれを行うことができるはずです。

明確にするために:
- 質問: Linux で誰かが pty (疑似端末) のスレーブ側を開いたとき、どのように検出できますか?
- pty のスレーブ側を開いているリーダーに、リーダーが pty を開いた後に厳密に書き込まれたデータを受信させたい (リーダーがスレーブ側を開く前に、マルチ書き込みプロセスがしばらくの間データを書き込むだけの場合、データはバッファリングされ、最終的に、ライターはブロックされ、スレーブ リーダーは、開くとすぐにすべてのバッファリングされたデータを取得します。これは、時間的にすぐ近くで生成されたデータのみを取得する 必要
があるため、望ましく ありません)。 isatty() や tcsetattr() などの名前付きパイプ、ソケットなどは、既存のバイナリが機能するように OK である必要があります。

4

2 に答える 2

17

これが見つからない理由は、特にそれを許可するための文書化されたインターフェースがないためです。ただし、それを可能にするトリックがあります。疑似端末マスター (ここではファイル記述子であると想定ptm) を開いた後、スレーブ側を開いてすぐに閉じます。

close(open(ptsname(ptm), O_RDWR | O_NOCTTY));

これにより、tty マスターに HUP フラグが設定されます。HUP フラグを定期的にポーリングするようになりましたpoll()(たとえば、データ ソースからデータが入ってくるたびに):

struct pollfd pfd = { .fd = ptm, .events = POLLHUP };
poll(&pfd, 1, 10 /* or other small timeout */);

if (!(pfd.revents & POLLHUP))
{
    /* There is now a reader on the slave side */
}

リーダーが離れた場合は、POLLHUP再度設定されます。

あなたの場合、特定の pty にリーダーがあるかどうかを 1 つのループから次のループに覚える必要さえないでしょread()poll()。設定されていないそれらのいずれかにデータを送信しますPOLLHUP

于 2010-08-16T02:09:54.423 に答える
4

スレーブ pty に inotify ウォッチを追加し、それをポーリングします。open で inotify イベントを取得できます。その後、inotify ファイル記述子とマスター pty ファイル記述子をポーリングできます。オープン (IN_OPEN) の inotify イベントを取得できます。これにより、スレーブ側が開かれたときにポーリングのブロックが解除されます。

于 2011-04-23T03:56:48.527 に答える