Subject: Re: lseek(2) & read(2) on raw cd(4) device
To: None <tech-kern@netbsd.org>
From: Sean Doran <smd@ebone.net>
List: tech-kern
Date: 08/24/2000 21:01:20
Oops, the program.

        Sean.
- --
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

char cd_device[] = "/dev/rcd0d";

void test_lseek(int, off_t, int);
void read_a_block(int);

int do_read = 1;

int
main(argc, argv) 
     int argc;
     char *argv[];
{

  int fd;

  if(argc==2 && strncmp(argv[1], "-noread", 7) == 0)
    do_read = 0;

  
  if((fd=open(cd_device, O_RDONLY)) < 0) {
    perror("couldn't open cd_device");
    exit(1);
  }

  /* straightforward - position to start, position to start of 1st block */
  test_lseek(fd, (off_t)     0L, SEEK_SET);
  test_lseek(fd, (off_t)  2048L, SEEK_SET);
  
  /* where is the device's end? */
  test_lseek(fd, (off_t)     0L, SEEK_END);

  /* from the disklabel:
     total sectors: 296118
     bytes/sector: 2048
  */
  /* seek to end but one sector, print where we are */
  test_lseek(fd, (off_t)   2048L * 296116L, SEEK_SET);
  test_lseek(fd, (off_t)                0L, SEEK_CUR);

  /* seek two forward, print where we are - shouldn't be able to do this */
  test_lseek(fd, (off_t)      2L *   2048L, SEEK_CUR);
  test_lseek(fd, (off_t)                0L, SEEK_CUR);

  /* seek waaaaaay past the end, print where we are - shouldn't be able to do this */
  test_lseek(fd, (off_t) 2L * 2048L * 296116L, SEEK_SET);
  test_lseek(fd, (off_t) 		   0L, SEEK_CUR);

  /* try again at end, print where we are */
  test_lseek(fd, (off_t) 0L, SEEK_END);
  test_lseek(fd, (off_t)           0L, SEEK_CUR);

  /* try again at block 4, print where we are */
  test_lseek(fd, (off_t) 4L *   2048L, SEEK_SET);
  test_lseek(fd, (off_t)           0L, SEEK_CUR);
  exit(0);
  
}

void
test_lseek(fd, offset, whence)
     int fd;
     off_t offset;
     int whence;
{
  off_t res;

  if(((res=lseek(fd, offset, whence)) < (off_t)0L) || errno != 0) {
    fprintf(stderr, "errno = %d ", errno);
    perror("doing lseek");
    return;
  } else {
    printf("lseek(%d, %lu, %d) -> %lu\n", fd, (unsigned long)offset, whence, (unsigned long)res);
    read_a_block(fd);
    return;
  } 
}

void
read_a_block(fd)
     int fd;
{

  char buf[2048];
  ssize_t n;

  if(do_read == 0) 
    return;

  if((n=read(fd, buf, 2048)) < 0 || errno != 0) {
    fprintf(stderr, "errno = %d  ");
    perror("read failed");
  } else 
    printf("block read OK\n");
}