Mail Archives: djgpp-workers/2001/10/20/17:13:59
According to Richard Dawe:
> ---START bigseek.c---
> /*
> * bigseek.c
> * Try big relative seeks with DJGPP CVS (aka 2.04?)
> * Written by Richard Dawe <rich AT phekda DOT freeserve DOT co DOT uk>
> */
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <unistd.h>
> #include <assert.h>
>
> int
> main (int argc, char *argv[])
> {
> char *filename;
> struct stat sbuf;
> unsigned long sz;
> ssize_t n;
> char buf[4];
> off_t o;
> int fd;
>
> /* 2GB + 100MB */
> const unsigned long big_offset = (1024UL * 1024UL * 1024UL * 2UL)
> + (1024UL * 1024UL * 100UL);
>
> /* 2GB + 10MB */
> unsigned long big_offset2 = (1024UL * 1024UL * 1024UL * 2UL)
> + (1024UL * 1024UL * 10UL);
>
> assert(big_offset2 < big_offset);
>
> if (argc < 2) {
> fprintf(stderr, "Oi! Where's me file?\n");
> return(EXIT_FAILURE);
> }
>
> /* Does the file exist? How big is it? */
> filename = argv[1];
>
> if (stat(filename, &sbuf) < 0) {
> perror(argv[0]);
> return(EXIT_FAILURE);
> }
>
> if (!S_ISREG(sbuf.st_mode)) {
> fprintf(stderr, "%s is not a regular file!\n", filename);
> return(EXIT_FAILURE);
> }
>
> /* Check the file's bigger than 2GB. */
> sz = (unsigned long) sbuf.st_size;
>
> if (sz <= big_offset) {
> fprintf(stderr, "%s is not bigger than %lu (%luMB)!\n",
> filename, big_offset, big_offset / (1024UL * 1024UL));
> return(EXIT_FAILURE);
> }
>
> /* Now open the file and try out some big relative seeks (> 2GB
> movement). */
> fd = open(argv[1], O_RDONLY|O_BINARY);
>
> o = lseek(fd, big_offset, SEEK_SET);
> printf("Offset %lu (desired = %lu)\n", (unsigned long) o, big_offset);
> o = lseek(fd, big_offset2, SEEK_CUR);
> printf("Offset %lu (desired = %lu)\n", (unsigned long) o,
> big_offset + big_offset2);
>
> printf("big_offset - big_offset2 = %lu\n", big_offset - big_offset2);
> printf("big_offset + big_offset2 = %lu\n", big_offset + big_offset2);
> printf("(off_t) big_offset2 = %d\n", (off_t) big_offset2);
>
> /* Return to the start, seek to beyond 2GB, try a read. Then try
> * a large (2GB - 1) backwards seek. */
> o = lseek(fd, 0, SEEK_SET);
> printf("Offset %d\n", o);
> o = lseek(fd, big_offset, SEEK_CUR);
> printf("Offset %d\n", o);
>
> n = read(fd, buf, sizeof(buf));
> if (n < sizeof(buf)) {
> fprintf(stderr, "Read at offset %d (aka %lu?) failed\n",
> o, (unsigned long) o);
> close(fd);
> return(EXIT_FAILURE);
> } else {
> printf("Read at offset %d (aka %lu?) OK\n", o, (unsigned long) o);
> }
> o = lseek(fd, -sizeof(buf), SEEK_CUR); /* Return to pre-read position */
>
> o = lseek(fd, -(off_t)((1024UL * 1024UL * 1024UL * 2UL) - 1UL),
> SEEK_CUR);
> printf("Offset %d\n", o);
>
> printf("big_offset - 2GB - 1 = %lu\n",
> big_offset - ((1024UL * 1024UL * 1024UL * 2UL) - 1UL));
>
> /* Done with file */
> close(fd);
>
> return(EXIT_SUCCESS);
> }
> ---END bigseek.c---
Here's the results:
Offset 2252341248 (desired = 2252341248)
Offset 115343360 (desired = 115343360)
big_offset - big_offset2 = 94371840
big_offset + big_offset2 = 115343360
(off_t) big_offset2 = -2136997888
Offset 0
Offset -2042626048
Read at offset -2042626048 (aka 2252341248?) OK
Offset 104857601
big_offset - 2GB - 1 = 104857601
Right,
MartinS
- Raw text -