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;
}
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
.