On Friday 15 October 2004 22:19, dbs2 wrote:
> Daca am urmator cod in C, prin care incerc sa deschid un fisier mai mare de
> 4 GB folosind tipul off64_t, open64, lseek64
Prima chestiune pe care ar trebui sa o ai in minte este ca nu e bine sa ii
folosesti direct tipul off64_t, ci sa folosesti tipul off_t. De asemenea, o
chestiune care ar trebui sa o stii deja - lungimile tipurilor nu sunt fixe.
int-ul era pe 16 biti pe DOS si e de 32 de biti pe Linux. Iar pe sistemele cu
64 de biti exista un model care accepta int-ul tot pe 32 de biti iar long-ul
pe 64 (tocmai pentru a nu busi programele care presupuneau ca sizeof(int)=4)
si alt model care pune int si long pe 64 de biti. Ti-as da un link catre
articol, dar memoria nu ma ajuta pe moment.
Un mic exemplu:
test2.c:
#include <stdio.h>
#include <sys/types.h>
int main (void)
{
printf ("sizeof(off_t)=%d\n", sizeof(off_t));
return 0;
}
Rulari:
cc -Wall test2.c -o test2
[EMAIL PROTECTED] spooky]$ ./test2
sizeof(off_t)=4
cc -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 test2.c -o test2
[EMAIL PROTECTED] spooky]$ ./test2
sizeof(off_t)=8
In ceea ce priveste problema ta, nu ar trebui sa folosesti direct nici
functiile open64, lseek64. Pur si simplu nu sunt portabile - si nu are sens
sa folosesti functiile asa cand sistemul iti ofera un layer de portabilitate
la nivel de sursa. Think POSIX.
Ceea ce trebuie sa faci tu acolo este sa ai ceva de genul:
test3.c:
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main (void)
{
int fd;
off_t offset;
offset = 5000000000;
fd = open ("fisier.cu.date(pentru ca nu e 8.3)", O_RDWR);
lseek (fd, offset, SEEK_SET);
close (fd);
return 0;
}
Compilare:
cc -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 test3.c -o test3
Desigur, asta separa problema aproape 'nenatural' in doua - o parte in
sursa, o parte in compilare. Insa sursa ta nu depinde de niste define-uri
suspecte care poate nu au sens (sau au alta semnificatie) pe alte sisteme.
Cat despre compilare, asta e o alta problema - si are o alta solutie - este
una din ratiunile din spatele existentei sistemului autotools.
Apropos, o alta greseala pe care ai facut-o este sa folosesti extensia GNU
"long long". Don't. O sa ti se para un pic paradoxal, dar avand in vedere
scopul tau de-acolo este mult mai sigur sa folosesti int64_t. Tipurile
(u_)int(dimensiune)_t sunt standard ?POSIX/SUS? (cineva sa ma corecteze
aici), si este mai bine sa le folosesti - fiecare compilator le va defini asa
cum trebuie (chiar ca o structura high/low, daca e cazul) in <sys/types.h>.
De altfel, as modifica si programul de mai sus cu:
--- test3.c Sat Oct 16 10:14:53 2004
+++ test4.c Sat Oct 16 10:36:27 2004
@@ -6,7 +6,8 @@
{
int fd;
off_t offset;
- offset = 5000000000;
+ u_int64_t off1 = 5000000000;
+ offset = off1;
fd = open ("fisier.cu.date(pentru ca nu e 8.3)", O_RDWR);
lseek (fd, offset, SEEK_SET);
close (fd);
(cu varianta asta scapi de un warning in caz de compilare eronata, riscand
evident sa nu ai fie chiar ce iti doresti in apelul lseek. Dar, cum spunea
articolul recomandat de unul din cei care ti-au raspuns mai sus
(http://freshmeat.net/articles/view/709/), always check the return value of
lseek).
Acum, ca te-am dat peste cap de tot, iti urez happy programming,
Dorin
---
Detalii despre listele noastre de mail: http://www.lug.ro/