Подпроцесс pnmtops зависает при вызове из скрипта scanadf

Подпроцесс pnmtops зависает при вызове из скрипта scanadf

Я с удовольствием пользуюсь scanadfэтими -S script --script-wait параметрами уже пару лет.

Мой скрипт, называемый scan_perpage, преобразует данные изображения в PDF с помощью вызова pnmtops, переданного через ps2pdf.

Однако недавно (я подозреваю, что с тех пор, как я обновился с Fedora 17 до 19) вызванный скрипт завис, и поэтому scanadfзавис. Скрипт завис на pnmtopsкоманде. pnmtopsСама команда ждет pnmtopsзавершения своего ответвленного "дочернего" выходного фильтра, и этого так и не происходит.

Запуск scan_perpageскрипта непосредственно на странице raw scanner работает нормально. Запуск pnmtopsкоманды напрямую тоже работает нормально. Только при запуске из scanadfvia -Sскрипт зависает на pnmtops.

Версии:

# 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:

Я нашел и исправил ошибку, вызывающую этот симптом. [...] Исправление есть в Netpbm 10.64.02.

Разница в среде, которая иногда заставляет Pnmtops зависать, а иногда нет, заключается в количестве открытых файлов. Если при вызове Pnmtops открыто более 10 файлов, происходит зависание.

Если вам интересно, в чем заключается патология: дочерний процесс завершается, когда канал, который его кормит, подает сигнал EOF. Это происходит, когда каждая копия файлового дескриптора для отправляющего конца канала закрывается. Единственная копия, которая должна существовать, — это та, в которую родительский процесс записывает данные. Но дочерний процесс обязательно наследует копии файловых дескрипторов для обоих концов канала. Если дочерний процесс не закрывает свою копию отправкав конце трубы ребенок никогда не увидит EOF на принимающем конце, поэтому будет ждать вечно.

Это означает, что дочерний процесс должен закрыть свою копию отправляющего конца канала, который его питает. Чтобы сделать это и исправить некоторые другие подобные проблемы, дочерний процесс пытается при запуске закрыть каждый файловый дескриптор, кроме двух, которые он фактически использует. Но POSIX не предоставляет способа узнать список открытых файловых дескрипторов, поэтому дочерний процесс просто слепо закрывает 0-9 (исключая два необходимых ему), зная, что Pnmtops не будет использовать больше файлов. Ошибка заключалась в том, что программа не учитывала файловые дескрипторы, с которыми родился процесс. Исправление заключается в том, чтобы Pnmtops закрывал файловые дескрипторы 0-9 при запуске, так что все созданные им каналы будут иметь номера файловых дескрипторов в диапазоне 0-9 и, таким образом, будут закрыты слепым закрытием 0-9.

Связанный контент