Windows 2000と XP SP2には CreatePipe のバグがあるらしい

Windows 2000で Cygwin API 0.341 を動かしてみたところ…
前回の記事の不具合を調査していたところこんな文書が出てきた

Use CreateNamedPipe instead of CreatePipe, because the latter returns a write handle that does not permit FILE_READ_ATTRIBUTES access, on versions of win32 earlier than WinXP SP2.
CreatePipe also stupidly creates a full duplex pipe, which is a waste, since only a single direction is actually used.
It's important to only allow a single instance, to ensure that the pipe was not created earlier by some other process, even if the pid has been reused.
Note that the write side of the pipe is opened as PIPE_TYPE_MESSAGE.
This *seems* to more closely mimic Linux pipe behavior and is definitely required for pty handling since fhandler_pty_master writes to the pipe in chunks, terminated by newline when CANON mode is specified.

CreatePipeの代わりにCreateNamedPipeを使用します。後者は、WinXP SP2より前のバージョンのwin32で、FILE_READ_ATTRIBUTESアクセスを許可しない書き込みハンドルを返すためです。
CreatePipeはまた、実際には一方向のみが使用されるため、無駄な全二重パイプを愚かに作成します。
pidが再利用されている場合でも、パイプが他のプロセスによって以前に作成されていないことを確認するために、単一のインスタンスのみを許可することが重要です。
パイプの書き込み側はPIPE_TYPE_MESSAGEとして開かれていることに注意してください。
これは、Linuxパイプの動作をより厳密に模倣しているようであり、fhandler_pty_masterがパイプにチャンクで書き込み、CANONモードが指定されている場合は改行で終了するため、pty処理に必ず必要です。

まじかよ・ω・

PeekNamedPipe() hangs

サンプルがあった

CreatePipe res=1
+peek
Writer res=1 dw=4
Reader res=1 dw=4
-peek res=1 avail=0
+peek
Writer res=1 dw=4
Reader res=1 dw=4
-peek res=1 avail=0
+peek
Writer res=1 dw=4
Reader res=1 dw=4
-peek res=1 avail=0
+peek
Writer res=1 dw=4
Reader res=1 dw=4
-peek res=1 avail=0

本来はこうなる

CreatePipe res=1
+peek
-peek res=1 avail=0
+peek
-peek res=1 avail=0
+peek
-peek res=1 avail=0
+peek
Writer res=1 dw=4
Reader res=1 dw=4
Writer res=1 dw=4
Reader res=1 dw=4
Writer res=1 dw=4
Reader res=1 dw=4
Writer res=1 dw=4
Reader res=1 dw=4
Writer res=1 dw=4
Reader res=1 dw=4
なんかバグってますね…。

なお、XPSP2は、Aug 15, 2008 にHotfixで直ってるという
多分、2008/8/14リリースの MS08-066 の NTOSKRNLのHotfixがそうだと思う。
ちなみに、Windows 2000は影響がないとして修正されなかった。

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です