fopen illegal seek

 ( danee | 2005. április 28., csütörtök - 2:06 )

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

[quote:d57796064b="egmont"][quote:d57796064b="meditor"]Azért megnézném. hogy az fopen nem NULL-lal tér-e vissza.[/quote:d57796064b]
Én úgy látom, hogy meg is nézi :-)
[quote:d57796064b]Kezeld binárisan a fájlt(a text-es fájlkezelés adatvesztést
okozhat! )[/quote:d57796064b]
Unix rendszerek alatt nincs különbség a kétfajta megnyitás között. Windows, Cygwin stb. alatt lehet eltérés.
[quote:d57796064b]seekelj be a végére megnyitás után (fseek)[/quote:d57796064b]
Ha append módban nyitsz meg egy fájlt, akkor automatikusan minden írási művelet a fájl végére történik, helyi fájlrendszer esetén (NFS-en sajnos nem) oszthatatlan atomi műveletként a fájl végére seek-el és oda ír. Ha csak egy processz írja a fájlt, akkor ez tök ugyanaz, mint sima write módban megnyitni és a végére tekerni, de amint több processz is írja a naplófájlt, a kézzel seekelgetés versenyhelyzethez vezet, ami adatvesztést okozhat. Épp erre való az append mód, amit danee kódja is használ.[/quote:d57796064b]

Ja,ja, Őnnek többnyire igaza van (-::

Hali!

Van egy fv-em, ami annyit tesz, hogy fog egy fájlt, és az utolsó sorkén hozzáfűz valami szöveget. Namármost ha a main fv-ből hivom meg, tökéletesen jól végrehajtódik és a szöveg belekerül a fájlba, ellenben ha bármielyen más fv hivja meg, akkor az fopen illegal seek üzenettel elszáll.

Mit ronthattam el?

Rövidítve a kód, amivel a gondom van:

[code:1:a51fc279f8]

void mylog(const char * msg ) {
FILE *fp;
fp = fopen("/var/log/log.log","a+");
if ( fp != NULL ) {
fputs( msg, fp) ;
fclose(fp);
}
}

void valamifv() {
mylog("Ird bele");
}

int main( int argc, char **argv ) {
// kod
mylog("Ird bele");
// tobbi kod
return 0;
}
[/code:1:a51fc279f8]

Előre is köszi a segítséget!

ennek így működnie kellene, de hogy efelől megbizonyosodjak ki is próbáltam és valóban működik. szerintem más bajod lehet - vagy én értettem félre valamit.
a mylog()-ot meghívtam main()-ből és valamifv()-ből is és mindkét esetben működött.
egy fp = NULL nem ártana mondjuk :)

[quote:6e835da94d="wry"]egy fp = NULL nem ártana mondjuk :)[/quote:6e835da94d]
Hova a bánatba? Lokális változója a mylog-nak, amelynek rögtön az elején értéket adok, mi ezzel a gond?
Nekem inkább az a gyanús, hogy ez itt egy rövidített kód, míg esetleg az eredetiben nem pont így vannak a dolgok.

Azért megnézném. hogy az fopen nem NULL-lal tér-e vissza.

Kezeld binárisan a fájlt(a text-es fájlkezelés adatvesztést
okozhat! ), seekelj be a végére megnyitás után (fseek), és
a logstringet nem ártana lezárni egy 0xa-val.

Fontos! a karakter lezáró 0 string nem kerül ki az állományba
az fputs-sal. Neked tehát lesz egy ömlesztett szöveged, amelyben
az egyes stringeket sem 0 (zéró) sem 0xa (LF) nem határolja. Hogyan
akarod feldolgozni ezek után?

Ém azt szoktam csinálni, hogy space-el fetöltök egy mondjuk
64 byte hosszú mezőt, memmove-val belemozgatom a logstringet
és a 0+63. byteba 0xa-t teszek. Ezekután:

fopen() - logfile
fseek() - fájlvége
fwrite() - logstring
flush() - logfile
fclose() - logfile

Így minden logsorom azonos hosszú lesz, nagyon könnyű
az áttekintése és a feldolgozása is.

[quote:1cae4ffb0c="Zahy"][quote:1cae4ffb0c="wry"]egy fp = NULL nem ártana mondjuk :)[/quote:1cae4ffb0c]
Hova a bánatba? Lokális változója a mylog-nak, amelynek rögtön az elején értéket adok, mi ezzel a gond?
Nekem inkább az a gyanús, hogy ez itt egy rövidített kód, míg esetleg az eredetiben nem pont így vannak a dolgok.[/quote:1cae4ffb0c]

azt hittem, hogy a "nem ártana" és a "kell" közötti különbséget azért észre lehet venni :/
a fenti kódrészletben egyértelműen felesleges, mivel az fp a következő sorban értéket kap - ahogy azt te is megmondtad.
a "nem ártana" az pontosan azt jelenti amit. hívhatod rossz beidegződésnek, de szeretem ha a (lokális) pointer NULL-ra mutat alapban, legalább később nem érnek meglepetések.

Zahy azt igyekezett megvilágítani, hogy az fp=fopen(); ugyanolyan
értékadás, mint az fp=NULL, egymásutáni alkalmazásuk esetén
az utolsónak lesz csak hatása, tehát az egyik fölösleges.

Teljesen más a helyzet, ha az fopen egy if() mögött van, de itt erről
szó sincs.

Fölöttébb bizarr.
Próbáld "a+" helyett "a" módban megnyitni.
Warning nélkül fordul "gcc -Wall" esetén is? stdio.h include-olva van?
Esetleg különféle optimalizálásokkal (-O0, -O1, -O2, -O3, -Os) próbálkoznék, hogy vajon mindenütt fennáll-e a hiba.
Másik disztrib alatt ki tudnád próbálni? Hátha a glibc vagy gcc a hibás.
Továbbá a progi futásáról strace kivonat a két (sikeres és sikertelen) esetre is segíthet.

Ésmég: errno lekérdezés, vag kiiratása perror()-ral

[quote:9653bfa416="meditor"]Azért megnézném. hogy az fopen nem NULL-lal tér-e vissza.[/quote:9653bfa416]
Én úgy látom, hogy meg is nézi :-)
[quote:9653bfa416]Kezeld binárisan a fájlt(a text-es fájlkezelés adatvesztést
okozhat! )[/quote:9653bfa416]
Unix rendszerek alatt nincs különbség a kétfajta megnyitás között. Windows, Cygwin stb. alatt lehet eltérés.
[quote:9653bfa416]seekelj be a végére megnyitás után (fseek)[/quote:9653bfa416]
Ha append módban nyitsz meg egy fájlt, akkor automatikusan minden írási művelet a fájl végére történik, helyi fájlrendszer esetén (NFS-en sajnos nem) oszthatatlan atomi műveletként a fájl végére seek-el és oda ír. Ha csak egy processz írja a fájlt, akkor ez tök ugyanaz, mint sima write módban megnyitni és a végére tekerni, de amint több processz is írja a naplófájlt, a kézzel seekelgetés versenyhelyzethez vezet, ami adatvesztést okozhat. Épp erre való az append mód, amit danee kódja is használ.

Zahynak igaza volt, tényleg máshol volt elirva, bár most annak ellenére h irja az illegal seek hibát legalább beleirja amit kell.

Ez egy beadandóm része volt, a lényeg hogy most megy, ott ugysem erre fognak koncentrálni elsősorban, bár a loggolás fontos része a dolognak...

Köszi mindenkinek a segítséget!