Der Unterprozess von pnmtops bleibt hängen, wenn er von einem Scanadf-Skript aufgerufen wird

Der Unterprozess von pnmtops bleibt hängen, wenn er von einem Scanadf-Skript aufgerufen wird

Ich arbeite seit einigen Jahren zufrieden scanadfmit den Parametern.-S script --script-wait

Mein Skript mit dem Namen scan_perpagekonvertiert die Bilddaten über einen Aufruf von in PDF und pnmtopswird durchgeleitet ps2pdf.

Doch seit Kurzem (ich vermute, seit ich von Fedora 17 auf 19 aktualisiert habe) hängt das aufgerufene Skript und bleibt deshalb scanadfhängen. Das Skript bleibt beim pnmtopsBefehl hängen. Der pnmtopsBefehl selbst wartet darauf, dass sein gegabelter „untergeordneter“ pnmtopsAusgabefilter abgeschlossen wird, und das wird nie der Fall.

Das Ausführen des scan_perpageSkripts direkt auf der Rohausgabe der Scannerseite funktioniert einwandfrei. Das direkte Ausführen des Befehls funktioniert ebenfalls einwandfrei. Nur wenn das Skript über pnmtopsausgeführt wird, bleibt es bei hängen .scanadf-Spnmtops

Versionen:

# 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

Hier ist die Ausgabe meines scanSkripts, das aufruft 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>

Hier ist der Prozessbaum an der Stelle, an der das Problem aufhört:

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

Prozess 10904 (der gegabelte pnmtops„Ausgabefilter“) wird nie beendet. Ein Strace zeigt an, dass er auf einen „Read“ wartet.

Ich kann nicht herausfinden, warum pnmtopses hängt, wenn es über aufgerufen wird scanadf, aber wenn es direkt über dieselbe Datei aufgerufen wird, funktioniert es einwandfrei.

Darüber hinaus pnmtopsläuft alles problemlos weiter, wenn der Unterprozess manuell beendet wird.

Antwort1

Von Bryan Henderson, Betreuer von netpbm:

Ich habe einen Fehler gefunden und behoben, der dieses Symptom verursacht. [...] Der Fix ist in Netpbm 10.64.02.

Der Umgebungsunterschied, der dazu führt, dass Pnmtops manchmal hängt und manchmal nicht, ist die Anzahl der geöffneten Dateien. Wenn beim Aufruf von Pnmtops mehr als 10 Dateien geöffnet sind, bleibt es hängen.

Falls Sie sich für die Pathologie interessieren: Das Kind wird beendet, wenn die Pipe, die es versorgt, EOF signalisiert. Das passiert, wenn jede Kopie des Dateideskriptors für das sendende Ende der Pipe geschlossen wird. Die einzige Kopie, die vorhanden sein sollte, ist die, in die der übergeordnete Prozess Daten schreibt. Aber das Kind erbt notwendigerweise Kopien der Dateideskriptoren für beide Enden der Pipe. Wenn das Kind seine Kopie des Dateideskriptors nicht schließt, VersendungEnde der Leitung, das Kind wird EOF am empfangenden Ende nie sehen und daher ewig warten.

Das bedeutet, dass das Kind seine Kopie des sendenden Endes der Pipe, die es versorgt, schließen muss. Um dies zu tun und einige andere ähnliche Probleme zu beheben, versucht das Kind beim Start, alle Dateideskriptoren außer den beiden zu schließen, die es tatsächlich verwendet. Aber POSIX bietet keine Möglichkeit, die Liste der offenen Dateideskriptoren zu kennen, also schließt das Kind einfach blind 0-9 (außer den zwei, die es braucht), da es weiß, dass Pnmtops nicht mehr Dateien als diese verwenden würde. Der Fehler bestand darin, dass das Programm die Dateideskriptoren, mit denen der Prozess geboren wurde, nicht berücksichtigte. Die Lösung besteht darin, dass Pnmtops beim Start die Dateideskriptoren 0-9 schließt, sodass alle von ihm erstellten Pipes Dateideskriptornummern im Bereich 0-9 haben und somit durch das blinde Schließen von 0-9 geschlossen werden.

verwandte Informationen