Tenho usado felizmente scanadf
os -S script --script-wait
parâmetros há alguns anos.
Meu script, chamado scan_perpage
, converte os dados da imagem em pdf, por meio de uma chamada para pnmtops
, canalizada ps2pdf
.
No entanto, recentemente (suspeito que desde que atualizei do Fedora 17 para 19), o script chamado trava e, portanto, scanadf
trava. O script está suspenso no pnmtops
comando. O pnmtops
comando em si está aguardando a pnmtops
conclusão do filtro de saída "filho" bifurcado, o que nunca acontece.
Executar o scan_perpage
script diretamente na saída bruta da página do scanner funciona bem. Executar o pnmtops
comando diretamente também funciona bem. É somente quando executado scanadf
via -S
que o script trava em pnmtops
.
Versões:
# 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
Aqui está a saída do meu scan
script, que chama 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>
Aqui está a árvore do processo no ponto de travamento:
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
O processo 10904 (o pnmtops
"filtro de saída" bifurcado) nunca termina. Um strace indica que está aguardando uma "leitura".
Não consigo entender por que pnmtops
trava quando chamado via scanadf
, mas quando chamado diretamente no mesmo arquivo funciona perfeitamente.
Além disso, se o pnmtops
subprocesso for eliminado manualmente, tudo continua sem problemas.
Responder1
De Bryan Henderson, mantenedor do netpbm:
Encontrei e corrigi um bug que causa esse sintoma. [...] A correção está no Netpbm 10.64.02.
A diferença no ambiente que faz com que o Pnmtops às vezes trave e às vezes não é o número de arquivos abertos. Se houver mais de 10 arquivos abertos quando o Pnmtops for invocado, o travamento acontecerá.
Caso você se importe com qual é a patologia: A criança sai quando o cachimbo que a alimenta sinaliza EOF. Isso acontece quando todas as cópias do descritor de arquivo para a extremidade de envio do canal são fechadas. A única cópia que deveria existir é aquela na qual o processo pai está gravando dados. Mas o filho necessariamente herda cópias dos descritores de arquivo para ambas as extremidades do canal. Se a criança não fechar sua cópia do enviandoNa ponta do tubo, a criança nunca verá EOF na extremidade receptora, então esperará para sempre.
Isso significa que a criança deve fechar sua cópia na ponta emissora do cachimbo que a alimenta. Para fazer isso e corrigir alguns outros problemas semelhantes, o filho tenta, na inicialização, fechar todos os descritores de arquivo além dos dois que ele realmente usa. Mas o POSIX não fornece uma maneira de conhecer a lista de descritores de arquivos abertos, então o filho fecha cegamente de 0 a 9 (excluindo os dois necessários), sabendo que o Pnmtops não usaria mais arquivos do que isso. O erro foi que o programa não levou em conta os descritores de arquivo com os quais o processo nasceu. A correção é que o Pnmtops feche os descritores de arquivo 0-9 quando for inicializado, de modo que qualquer canal que ele criar tenha números de descritores de arquivo no intervalo de 0-9 e, portanto, seja fechado pelo fechamento cego 0-9.