Subject: lseek() misbehaving.
From: Jesper Eskilson <[email-masked]>
To: [email-masked]
Date: 28 Feb 2001 15:58:32 +0100

I've discovered what looks like bug in lseek(). Consider the following
program, which basically tries to read the first 32 bytes of /dev/fd0
twice, lseek():ing to the beginning between each read(). The output is:

bash$ ./rawdisk /dev/fd0
Filename = /dev/fd0
Doing lseek(3, 0, 0).
lseek() succeeded, new offset = 0

read() read 32 bytes (requested 32) from fd 3
=======
b8 c0 7 8e d8 b8 0 90 8e c0 b9 0 1 29 f6 29 ff fc f3 a5 ea 19 0 0 90 bf f4 3f 8e d8 8e d0 
=======

Doing lseek(3, 0, 0).
lseek() succeeded, new offset = 0

read() read 32 bytes (requested 32) from fd 3
=======
89 fc 8e e1 bb 78 0 1e 64 c5 37 b1 6 fc 57 f3 a5 5f 1f c6 45 4 24 64 89 3f 64 8c 47 2 30 e4 
=======
bash$

Now, you'd expect that the two 32-bytes block (32 is arbitrarily chosen)
would be identical, but they are not. The (second) call to lseek() does not
move the file-pointer at all, so the second 32-byte block is what you
would've gotten if you read 64 bytes the first time.

The source code of the program is included below.

/Jesper
-- 
-------------------------------------------------------------------------
Jesper Eskilson                                         [email-masked]
Virtutech                                         http://www.virtutech.se
-------------------------------------------------------------------------
/*
 * File:       rawdisk.c
 * Author:     Jesper Eskilson <[email-masked]>
 * Created:    26 February 2001
 * CVS:        $Id$
 * Time-stamp: <Last edited by jojo on Wed Feb 28 15:43:49 +0100 2001>
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

void do_read(int fd, int bytes, char *buf) {
  int n, i;

  n = read(fd, buf, bytes);

  if (n == -1) {
    perror("read() failed:");
  }

  printf("\nread() read %d bytes (requested %d) from fd %d\n", n, bytes, fd);

  printf("=======\n");
  for (i = 0; i < bytes; i++) {
    printf("%0x ", (unsigned char)buf[i]);
  }
  printf("\n=======\n");

  printf("\n");
  return;
}

void do_seek0(int fd, int whence, off_t offset) {
  int n_off;
  
  printf("Doing lseek(%d, %d, %d).\n", fd, offset, whence);
  
  if ((n_off = lseek(fd, offset, whence)) == (off_t)-1) {
      perror("lseek() failed");
    } else {
      printf("lseek() succeeded, new offset = %d\n", n_off);
    }
}
int main(int argc, char *argv[]) 
{
  char buf[4096];
  char *filename;
  int fd;
  if (argc != 2) {
    printf("Wrong number of arguments.\n");
    return -1;
  }

  filename = argv[1];

  printf("Filename = %s\n", filename);

  fd = open(filename, O_RDONLY | O_BINARY );

  if (fd == -1) {
    perror("open() failed:");
    return -1;
  }

  do_seek0(fd, SEEK_SET, 0);

  do_read(fd, 64, buf);

  do_seek0(fd, SEEK_SET, 0);

  do_read(fd, 32, buf);

  close(fd);

  return 0;
}

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple