scanadf スクリプトから呼び出されると pnmtops サブプロセスがハングする

scanadf スクリプトから呼び出されると pnmtops サブプロセスがハングする

私は数年間、パラメータscanadfを使用して満足して使用してきました。-S script --script-wait

私のスクリプトは、を呼び出し、scan_perpageを介してパイプすることで、画像データを PDF に変換します。pnmtopsps2pdf

しかし最近 (Fedora 17 から 19 にアップデートしてからだと思います)、呼び出されたスクリプトがハングし、その結果scanadfハングします。スクリプトはpnmtopsコマンドでハングします。pnmtopsコマンド自体は、フォークされた「子」出力フィルターが完了するのを待機していますpnmtopsが、完了することはありません。

scan_perpageスクリプトを生のスキャナー ページ出力で直接実行しても問題なく動作します。コマンドを直接実行しても問題なく動作します。スクリプトが でハングするのは、経由pnmtopsで実行した場合のみです。scanadf-Spnmtops

バージョン:

# rpm -q --info sane-backends
Name        : sane-backends
Version     : 1.0.23
Release     : 13.fc19

# rpm -q --info sane-frontends
Name        : sane-frontends
Version     : 1.0.14
Release     : 16.fc19

# rpm -q --info netpbm
Name        : netpbm
Version     : 10.61.02
Release     : 5.fc19

scan以下は、以下を呼び出すスクリプトの出力ですscanadf -vv

$ scan -o output.pdf
Scanning...
scanadf: value for --resolution is: 300
scanadf: scanning image of size 2544x3300 pixels at 1 bits/pixel
scanadf: acquiring gray frame
Started script `/usr/local/bin/scan_perpage' as pid=10902
Scanned document scan-0001
pnmtops: Input maxval is 1.  Postscript raster will have 1 bits per
sample, so maxval = 1
pnmtops: Image will be 610.56 points wide by 792.00 points high, left
edge 0.72 points from left edge of page, bottom edge 0.00 points from
bottom of page; NOT turned to landscape orientation
pnmtops: output filter spawned: pid 10904
pnmtops: Waiting for PID 10904 to exit
Scanned 1 pages
<the script hangs here>

ハングが発生した時点のプロセス ツリーは次のとおりです。

10897 32072 /bin/sh /usr/local/bin/scan -o output.pdf
10898 10897 scanadf -vvv -d fujitsu -S /usr/local/bin/scan_perpage
--script-wait --resolution 300 --mode Lineart -o scan-%04d
10902 10898 /bin/bash /usr/local/bin/scan_perpage scan-0001
10903 10902 pnmtops -verbose -imagewidth 8.5 -imageheight 11 scan-0001
10904 10903 pnmtops -verbose -imagewidth 8.5 -imageheight 11 scan-0001

プロセス 10904 (フォークされたpnmtops「出力フィルター」) は終了しません。strace は、それが「読み取り」を待機していることを示します。

pnmtops経由で呼び出されるとハングする理由がわかりませんscanadfが、同じファイルで直接呼び出されると完全に正常に動作します。

さらに、pnmtopsサブプロセスを手動で強制終了すると、すべてが問題なく続行されます。

答え1

netpbm のメンテナーである Bryan Henderson より:

この症状の原因となるバグを発見し、修正しました。[...] 修正は Netpbm 10.64.02 にあります。

Pnmtops がハングしたりハングしなかったりする環境の違いは、開いているファイルの数です。Pnmtops が呼び出されたときに開いているファイルが 10 個を超えると、ハングが発生します。

何が問題なのか知りたい方のために説明します。子プロセスは、パイプがEOFを送ったときに終了します。これは、パイプの送信側のファイル記述子のコピーがすべて閉じられたときに発生します。存在するはずのコピーは、親プロセスがデータを書き込んでいるコピーだけです。しかし、子プロセスは必然的にパイプの両端のファイル記述子のコピーを継承します。子プロセスがパイプのコピーを閉じない場合、 送信パイプの端では、子プロセスは受信側で EOF を見ることはないので、永遠に待機することになります。

つまり、子プロセスは、データを送っているパイプの送信側のコピーを閉じる必要があります。これを実行し、他の同様の問題を修正するために、子プロセスは起動時に実際に使用する 2 つのファイル記述子以外のすべてのファイル記述子を閉じようとします。しかし、POSIX では開いているファイル記述子のリストを知る方法が提供されていないため、子プロセスは、Pnmtops がそれ以上のファイルを使用しないことを承知の上で、必要な 2 つを除いて 0 から 9 までを盲目的に閉じます。間違いは、プログラムがプロセスが生成されたファイル記述子を考慮しなかったことです。修正方法は、Pnmtops が起動時にファイル記述子 0 から 9 を閉じるようにすることです。これにより、作成されるパイプのファイル記述子番号は 0 から 9 までの範囲になり、盲目的に 0 から 9 までを閉じることができます。

関連情報