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.
- 4951 megtekintés
Hozzászólások
select(), poll() ?
--
http://pyftpadmin.earthquake.hu
- A hozzászóláshoz be kell jelentkezni
select() +1, aztán ott lehet timeout
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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)
- A hozzászóláshoz be kell jelentkezni
Oke, bar eloszor lehet hogy tenyleg zamboriz kollega lentebbi megoldasat probalnam ki, ha ilyenfajta megolda's is elegendo". (nem ismertem a `timeout`-ot ;])
- A hozzászóláshoz be kell jelentkezni
> hogyan lehet leloni a popen() hivassal megnyitott/elinditott programot x ido mulva?
popen("timeout 10 pdftotext ...","r")
http://man7.org/linux/man-pages/man1/timeout.1.html
timeout [OPTION] DURATION COMMAND [ARG]...
Start COMMAND, and kill it if still running after DURATION.
- A hozzászóláshoz be kell jelentkezni
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).
- A hozzászóláshoz be kell jelentkezni
> 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.
- A hozzászóláshoz be kell jelentkezni
Persze, csak en ugy ertelmeztem a problemat, hogy max 10 masodpercet akar varni az eredmenyre, hogy mikor hal ki a pdftotext, az nem erdekes.
Ha fork+exec-kel indit, akkor nyilvan meglesz neki a gyerek PID-je, es ha lejart a timeout, siman kiloheti.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
erdekel, koszonom
--
"Pontosan ez a ti bajotok. Ez a kurva nagy csőlátás. [...]" (bviktor)
- A hozzászóláshoz be kell jelentkezni
Tessek: ExecCommandList
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni