Thread: copy files in reverse order using lseek

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    2

    copy files in reverse order using lseek

    Good evening, experts!

    I have question regarding file control and file descriptors using posix system calls

    I've got how to copy one file to another from start, but how could i modify the programme to copy it in reverse order? Source file should have read access and destination file read write execute. I have to use file control libraries.

    for example
    Code:
    FILE A            File B should be
    |---------|        |----------|
    |ABCDEF   |        |FEDCBA    |
    |---------|        |----------|

    I've tried to modify using lseek, but it does not giving me any result.

    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include<fcntl.h>
    #include<string.h>
    #include<sys/stat.h>
    #include<unistd.h>
    
    int main(int argc, char *argv[])
    {
    
    int source, dest, n;
    char buf;
    
    if (argc!=3)
    {
    fprintf(stderr,"usage %s <source> <dest>",argv[0]);
    exit(-1);
    }
    
    if ((source=open(argv[1], 0400))<0){
    fprintf(stderr,"error source");
    exit(-1);
    }
    if ((dest=creat(argv[2],0700))<0){
    fprintf(stderr,"error dest");
    exit(-1);
    }
    
    if ((lseek=(source,1,SEEK_END))<0)
    perror("lseek");
    
    while ((n=read(source,&buf,1))!=0)
    write(dest,&buf,1);
    
    
    
    write(STDOUT_FILENO,"OK",2);
    
    close(source);
    close(dest);
    
    
    
    return 0;
    }
    Could someone assist me please

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Compile with warnings turned all the way up:
    Code:
    $ gcc -Wall -g  reverse.c   -o reverse
    reverse.c: In function ‘main’:
    reverse.c:29: warning: left-hand operand of comma expression has no effect
    reverse.c:29: warning: left-hand operand of comma expression has no effect
    reverse.c:29: error: lvalue required as left operand of assignment
    You have an errant = between lseek and the opening parentheses. Also, you need to constantly re-seek the position in the file, i.e. lseek(source, -1, SEEK_END), then lseek(source, -2, SEEK_END), etc. Use that in your loop and keep doing it until you hit the beginning of the file.

    Also, *nix systems map the return value of int to an unsigned char, so returning -1 from main will actually result in an exit code of 255:
    Code:
    $ ./reverse 
    usage ./reverse <source> <dest>
    $ echo $?
    255
    Always return a value from 0 to 255 to be safe, never anything larger or negative.

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    If the file is not too large this may be easier to read the entire file into a buffer then write out the file backwards using this buffer.

    Remember that when you read a character the file pointer advances by one, so if you are trying to read from the last character in the file you must continually seek to the previous character, the file pointer will not advance backwards on its own.

    Jim

  4. #4
    Registered User
    Join Date
    Jan 2012
    Posts
    2
    Thanks, anduril462

    i've reworked the code

    here is the solution

    Code:
        #include<stdlib.h>
        #include<stdio.h>
        #include<fcntl.h>
        #include<string.h>
        #include<sys/stat.h>
        #include<unistd.h>
        
        int main(int argc, char *argv[]) {
        
            int source, dest, n;
            char buf;
            int filesize;
            int i;
        
            if (argc != 3) {
                fprintf(stderr, "usage %s <source> <dest>", argv[0]);
                exit(-1);
            }
        
            if ((source = open(argv[1], 0400)) < 0) { //read permission for user on source
                fprintf(stderr, "can't open source");
                exit(-1);
            }
        
            if ((dest = creat(argv[2], 0700)) < 0) { //rwx permission for user on dest
                fprintf(stderr, "can't create dest");
                exit(-1);
            }
        
            filesize = lseek(source, (off_t) 0, SEEK_END); //filesize is lastby +offset
            printf("Source file size is %d\n", filesize);
        
            for (i = filesize - 1; i >= 0; i--) { //read byte by byte from end
                lseek(source, (off_t) i, SEEK_SET);
        
                n = read(source, &buf, 1);
        
                if (n != 1) {
                    fprintf(stderr, "can't read 1 byte");
                    exit(-1);
                }
        
                n = write(dest, &buf, 1);
                if (n != 1) {
                    fprintf(stderr, "can't write 1 byte");
                    exit(-1);
                }
        
            }
            write(STDOUT_FILENO, "DONE\n", 5);
            close(source);
            close(dest);
        
        
        
            return 0;
        }

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Looks better. I'll trust that it works. Calling exit(-1) amounts to the same thing as returning -1 from main, in terms of the value passed back to the shell (yep, the return value of main or the value passed to exit() goes back to the shell). As I said before, it must be a value from 0 to 255. Negative numbers don't work in *nix systems. Make them exit(1) instead. Also, you should use perror or errno and strerror to print a more helpful error message. It will describe what the problem is, instead of just saying "something didn't work".

    Read the man page for open and creat carefully, and use the named flags they list instead of "magic numbers". O_RDONLY instead of 0400 and S_IRWXU instead of 0700.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 05-30-2010, 10:22 PM
  2. Reverse order printing
    By JFonseka in forum C Programming
    Replies: 1
    Last Post: 08-19-2007, 06:47 AM
  3. reverse the order of an array
    By dustyd in forum C++ Programming
    Replies: 4
    Last Post: 01-23-2003, 11:14 AM
  4. reverse order - arrays
    By Lillian in forum C Programming
    Replies: 12
    Last Post: 11-03-2002, 07:38 PM
  5. how do I reverse order of my array
    By jgonzales in forum C++ Programming
    Replies: 6
    Last Post: 09-25-2002, 03:48 PM

Tags for this Thread