ciolow-level-io

Low-level C I/O: When read from one file and write to another I'm hitting an infinite loop


I am working on an assignment that only allows use of low-level I/O (read(), write(), lseek()) as well as perror().

I have been able to open the nessisary in and out files with correct permissions, but when I output I get an infinite loop of the in file contents to out. See snippet below...

void *buf = malloc(1024);
while((n = read(in, buf, 1024)) > 0){
    if(lseek(in, n, SEEK_CUR) == -1){
        perror("in file not seekable");
        exit(-1);
    }
    while((m = write(out, buf, n)) > 0){
        if(lseek(out, m, SEEK_CUR) == -1){
            perror("out file not seekable");
            exit(-1);
        }
    }
    if(m == -1){ perror("error writing out"); exit(-1); }
}
if(n == -1){ perror("error reading in"); exit(-1); }

I have removed some error trapping from my code and you can assume the variables are initialized and includes statements are there.


Solution

  • Problem is the inner loop:

    while((m = write(out, buf, n)) > 0){
    

    should really be

    if((m = write(out, buf, n)) > 0){
    

    You only want buf to be written once, not infinitely many times. What you also need to handle is short writes, that is, when write returns with m < n && m > 0.

    Also, the lseek() calls are wrong, but they don't lead to the loop. read() and write() already advance the current file offset. You do not need to manually advance it, unless you want to skip bytes in the input or output file (note that in the output file case, on UNIX, skipping bytes may lead to so-called "holes" in files, regions which are zero but don't occupy disk space).