Lehet elég rossz megoldást választottam, de szeretnék neves pipe-ot olvasni.
Beállítottam rá egy select-et, ami szépen működik is. Bár kiolvasom a pipe-ot, és itt jön a gond, hogy én csak \n-ig akarom kiolvasni. de akár a fgets-et, akár fscanf-et használok, kiolvasás után a select visszadob, hogy van adat a pipe-ban, és annak olvasásakor Segmentation fault-ot kapok. Ha másképp nem megy ciklusba szervezem, de hátha van ötletetek, egy frappáns megoldásra.
köszi
- 1432 megtekintés
Hozzászólások
talan ha a kodot is megosztanad nem csak a problemat...
(ne felejtsd a < code > taget hasznalni - persze a ket szokoz nelkul).
- A hozzászóláshoz be kell jelentkezni
Hát nem egy nagy kódrész, az egész kicsit hosszú lenne. Akkor a lényeg:
pipe=open(config.pipe_location,O_RDONLY | O_NONBLOCK)
.
.
.
.
if(FD_ISSET(pipe,&setSocks))
{
FILE *stream;
stream = fdopen (pipe, "r");
fgets(data_buffer,sizeof(data_buffer)-1,stream);
# vagy ez: fscanf(stream,"%s\n",data_buffer);
fclose(stream);
}
De lehet hogy 0 hosszú, azaz üres pipe-ot nem tudok stream-re nyitni?
- A hozzászóláshoz be kell jelentkezni
És valóban egy üres pipe megnyitása stream-re nil-t eredményez. Vagy az a baj, hogy bezárom, és nem csak a stream záródik be?
- A hozzászóláshoz be kell jelentkezni
Ures pipe ebben az esetben azt jelenti hogy a masik alkalmazas nem nyitotta meg egyatalan a named fifo-t vagy azt, hogy megnyitotta, irkalt is bele valamit, de mar lezarta/kilepett? Mindesetre egy, a peer altal lezart fd-re ranyitni fdopen()-nel, az tenyleg nem lehet a legszebb (bar igazabol kerdes, hogy mit csinal az az fdopen()? elvileg buffer-elokeszitesen kivul mast nem nagyon kene; a `man fdopen` errol nem ir tul sokat).
- A hozzászóláshoz be kell jelentkezni
en ebben egyetlen arva selectet sem latok akarhogyan is eroltetem a szemem...
- A hozzászóláshoz be kell jelentkezni
ket megjegyzes:
- ne hasznalj NONBLOCK-ot. a nonblock rossz. foleg ha select()a'lsz is kozben.
- ne hasznalj bufferelt olvasast. bufferelt olvasas (fgets/fscanf/fread..., de ilyen az SSL_read(), ... stb is) rossz, ha select()a'lsz is kozben: i.e. lehet hogy mar 3 sor is benne van a bufferben, az fgets() ezt soronkent vissza is adja/adna', adat viszont nem jon a pipe-rol, tehat ket eset lehetseges: 1/ vagy nincs vege a file-nak, ekkor a select() blokkolni fog az idok vegezeteig 2/ vege van a file-nak, ekkor minden select() rogton visszater (eof is FD_ISSET-et valt ki, ha read allapotra pollozol) de ilyenkor a raolvasas, foleg ha bufferelt, csunya lehet, pl szegfault. Az fgets() fv-ek raadasul kicsit elbaltazva adjak vissza a file vege allapotot: egy
while ( ! feof(fr) ) { fgets(...); }
ciklussal duplan kapod pl vissza az utolso sort, ha az nem \n-re vegzodik (mindenfele select es egyeb bonya dolog nelkul is).
- A hozzászóláshoz be kell jelentkezni
köszi, megoldom másképp
- A hozzászóláshoz be kell jelentkezni
Igen, sajnos ebbe a problemaba en is tobbszor belefutottam (mondjuk inkabb socket-ekkel, de a lenyeg ugyanez). A megoldas mindig az volt, hogy tisztan read/write fv-k hasznalata + kezi buffereles, ugy semmi gond nem volt me'g. Ha kell egy kis egyszeru api erre, azt tudok kuldeni.
A.
- A hozzászóláshoz be kell jelentkezni
Nekem mindig a sorokra tores a gondom. A fgets azert jo, mert csak egy sort ad vissza \n nelkul, pont ezert szeretem hasznalni. Meg lehet ilyesmit oldani read/write-tal, azaz hogy soronkent olvassam a fajlt? Mennyire bonyi ezt megcsinalni?
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Az fgets is szerintem benne hagyja a \n-t, de lehet hogy rosszul emlekszem (igazabol az a legkevesebb, ha mondjuk utana a sorokat szokozok alapjan bontod darabokra).
Valami ilyesmit csinaltam anno a problema'ra:
linebuffer_reset(&lb);
while ( main_loop )
{ ...
FD_SET(f1,...)
FD_SET(f2,...)
select(max+1,...,...,...,...);
...
if ( FD_ISSET(fx,...) )
{ n=read(fx,tempbuff,tempbuffsize);
if ( n<0 )
{ /* error */ ... }
else if ( n==0 ) /* EOF */
{ line=linebuffer_flush(&lb);
if ( line != NULL )
{ do_something_with_partial_line(line);
free(line);
}
linebuffer_free(&lb);
}
else /* normal data */
{ linebuffer_concatenate(&lb,tempbuff,n);
while ( (line=linebuffer_fetch(&lb)) != NULL )
{ do_something_with_line(line);
free(line);
}
}
}
....
}
lenyeg, hogy a beolvasott adatot hozzacsapod egy bufferhez, majd egeszen addig, ameddig vannak benne "sorok", azaz \n-nel hatarolt reszek, azokat kiszeded, feldolgozod. A legvegen, EOF-kor pedig vagy tokures a buffer, vagy egy reszleges sor van benne (azaz nincs a vegen \n, kulonben az elozo ciklus kiszedte ma'r volna). Azzal kis kezdesz valamit, oszt annyi. A lenyeg, hogy senki sem garantalja, hogy 1/ a read()-dal beolvasol egy teljes sort 2/ a read()-dal pontosan 1 sort olvasol be, es nem mondjuk 137-et. szerk: 3/ azt sem hogy a file legvegen teljes sort talalsz. Ezeket mind kulon kell kezelni, sajnos.
- A hozzászóláshoz be kell jelentkezni
Engem igazabol a linebuffer_* megvalositasok erdekeltek volna...
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Pl. ennek a forrasaban benne van,
./src/linebuffer.[ch]
. Igazabol egy sima fifo, bar a konkret implementacio ennel joval primitivebb, sok overhead-del. De akkor teljesen jo (sot talan gyorsabb is, mint egy fifo), ha a tempbuffer merete nagysagrendileg megegyezik a sorok va'rhato' hosszaval vagy a program interaktivan reagal a bemenetre (eddig nalam mindket feltetel teljesult, azert se vacakoltam vele sokat).
A.
- A hozzászóláshoz be kell jelentkezni
Nekem azert nem performancia-kritikus, mert foleg konfig fajlok olvasasasnal jonnek ilyenek elo, hogy sorszinten kene kezelni a fajlt. Ahol lehet, igyekszek kulso konyvtarakkal dolgoztatni, mert azt nalam c-hez picit (oke, sokkal) jobban erto emberek raktak ossze.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Nekem azert nem performancia-kritikus, mert foleg konfig fajlok olvasasasnal jonnek ilyenek elo, hogy sorszinten kene kezelni a fajlt.
Mondjuk ebben az esetben egy read/write + egy kezzel irt buffereles kicsit agyu-vereb kategoria. Ha pipe-ok, socket-ek, sajat protokoll, bizonytalan halozat, konkurrens olvasas/iras van, es elkerulhetetlen a read/write hasznalata az mas kerdes. Konfig file-okra a fgets azert jo szokott lenni, ott a szuk keresztmetszet inkabb a sorhossz limitaltsag. De arra legalabb vannak jo kesz megoldasok (readline(), getline()). read/write + sorbufferelesre nincs, az teny.
- A hozzászóláshoz be kell jelentkezni