C Low level I/O : Why does it hang in the while loop?

320 Views Asked by At

I'm studying low-level I/O in C for the first time and I'm trying to write a program that prints a file backwards, but it seems that this while loop doesn't work. Why does it happen?

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

int main(){
    int n;
    int buf[BUFFSIZE];
    off_t currpos;

    int fd;
    if((fd = open("fileprova", O_RDWR)) < 0)
        perror("open error");

    if(lseek(fd, -1, SEEK_END) == -1)
        perror("seek error");

    while((n = read(fd, buf, 1)) > 0){
        if(write(STDOUT_FILENO, buf, n) != n)
            perror("write error");

        if(lseek(fd, -1, SEEK_CUR) == -1)
            perror("seek error");

        currpos = lseek(fd, 0, SEEK_CUR);
        printf("Current pos: %ld\n", currpos);
    }

    if(n < 0)
        perror("read error");

    return 0;

}
1

There are 1 best solutions below

1
Adrian Mole On BEST ANSWER

The call read(fd, buf, 1), if successful, will read one byte of data and then move the file pointer forward by one byte! The call lseek(fd, -1, SEEK_CUR) will then move the file pointer backward by one byte!

Net result: your while loop will continue to read the same byte forever!

Solution: Inside your while loop use the following to set the file pointer to read the previous byte: lseek(fd, -2, SEEK_CUR) - and break out of the loop when that call returns -1.