popen es a timeout

Fórumok

Adott egy C fuggveny, ami a pdftotext kimenetet olvassa popen()-nel megnyitva. Allitolag a pdftotext valamiert "hangs", es arra gondoltam, semmi gond, adjunk neki ~10 sec-et, aztan ha annyi ido alatt nem sikerult kiszedni a szoveget egy pdf-bol, akkor lelojuk a pdftotext-et. Csak az a baj, hogy a popen nem tamogat semmilyen timeout feature-t. A kerdes az, hogyan lehet leloni a popen() hivassal megnyitott/elinditott programot x ido mulva? A programnak tobb peldanya is fut egyszerre, igy siman lehet, hogy egyszerre tobb pdftotext processz is letezik, egymastol fuggetlenul.

A feladatot maskent megoldani (nem popen() segitsegevel) er. A lenyeg az, hogy a pdftotext /path/to/file.pdf eredmenyet megkapjam valahogy.

Hozzászólások

Igen, select() es/vagy poll() az tud kezelni timeout-ot, azzal nincs gond. Csak ha kifut a cucc az ido"bo"l es le akarod lo"ni, akkor arra ma'r nem lesz megoldas (pl nem tudod mi a process PID-je). A popen() kicsit fapados, "ipari" kornyezetben nem igazan hasznalnam/hasznalom.

Szoval ami kell, az: fork() + pipe() + dup2() + select() + kill() +wait(), megfelelo"en alkalmazva. Ha ma'r hasznaltad ezeket akkor relative konnyu osszerakni. Ha nem, majd me'g irok hogy hogysmint erdemes nekiindulni.

ok, irj majd :-) Viszont a leloves az egy must have feature, mert az teljesen jo, hogy a meghivo program tovabb tud lepni, es nem var orokke, de akkor idovel lesz egy csomo hanging processzem, amire mar a kutya sem kivancsi...

--
"Pontosan ez a ti bajotok. Ez a kurva nagy csőlátás. [...]" (bviktor)

Arra azert vigyazz, hogy a regi Debianokban (Etchben biztos, talan Lennyben is) levo timeoutnak mas, inkompatibilis parameterei vannak, mint az ujabbakban levonek (Squeeze utaniak), raadasul a timeout csomag nem is biztos, hogy minden gepen fel van telepitve. Javasolnam a fork+exec verziot, az a biztos (meg kill sem kell, amikor bezarod a pipe-ot, a gyerek processz kap egy SIGPIPE-ot, es kihal magatol).

> amikor bezarod a pipe-ot, a gyerek processz kap egy SIGPIPE-ot, es kihal magatol

Nem egészen, csak akkor kapna SIGPIPE-ot, amikor írna. Csakhogy épp az a megoldandó probléma, amikor nem ír.

http://man7.org/linux/man-pages/man7/pipe.7.html

If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process.

Eloturtam az exec fuggvenyeimet, amit egy programomban hasznalok: ket verzio is van, mindketto egy akarmilyen hosszu pipeline-t tud osszerakni, az elsonel a program olvassa a pipeline stdout-jat, a masodiknal egy file-ba van iranyitva a stdout. Van hozza egy egyszeru demo is, ha gondolod, elkuldom, annyi dolgod lesz csak vele, hogy a kimenetet fgets helyett select-tel olvasd.

Szokasos timeout stanza:

alarm(5);
s = popen(...)
alarm(0);
if (s < 0 && errno == EINTR) { /* timeout */
} else if (s < 0) { /* other error */
}

szerk: bar sanda gyanum hogy a popen()-t koveto read()/fgets()-en akarsz te igazabol timeout-olni.