5

I am quite new to C programming and lately I am trying to fiddle around with some low-level I/O functions in C on my x86 Linux system just to get a better understanding of the internal processes. As an excercise I decided to write a little program that should read data from a file and produce a hexdump-like output on the console. My program reads the first 512 bytes of the file and passes the buffer to a function that produces the output.

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#define BYTES 512

void printout(unsigned char *data){
        for (int i=0; i < BYTES; i++){
                if (i == 0 || i % 16 == 0) printf("%07x ",i);
                printf("%02x", data[i]);
                if (i % 2) 
                        printf(" ");
                if ((i + 1) % 16 == 0)
                        printf("\n");
        }
        printf("%07x\n",BYTES);
        return;
}

int main(int argc, char **argv){
        unsigned char data[BYTES];
        char *f;
        int fd;

        if(argv[1]==NULL){
                fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
                return EXIT_FAILURE;
        }

        f = argv[1];
        fd=open(f, O_RDONLY);

        if(fd == -1){
                fprintf(stderr, "Error: Could not open file %s\n", f);
                return EXIT_FAILURE;
        }

        read(fd, data, BYTES);
        printout(data);

        close(fd);
        return EXIT_SUCCESS;
}

Unfortunately, when I compare my output to hexdump or od, it seems that my program reverts the byte order.

$ myprogram /dev/sda |head -1
0000000 eb63 9000 0000 0000 0000 0000 0000 0000
$ hexdump /dev/sda |head -1
0000000 63eb 0090 0000 0000 0000 0000 0000 0000

As od -x --endian=little produces the same result as hexdump, I am certain that the problem is to be found in my code, I have no idea though. I would be grateful if anyone could explain to me why this happens and what I am missing respectively. I have searched the web but could not find anything helpful so far.

Thank you for your help!

Regards, Dirk

Dirk
  • 51
  • 2
  • 1
    maybe it is issue with hexdump, or its endianness; unrelated but make sure you check how many bytes you read and pass that to function instead of BYTES – Giorgi Moniava Mar 01 '16 at 10:10
  • 2
    Your code is fine. It's just processing one `unsigned char` at a time, while `hexdump` processes 16 bit at a time AFAICT, giving rise to endianess differences. This would've been a bit easier if you had picked a *reproducable* input instead of the contents of your hard drive. ;-) – DevSolar Mar 01 '16 at 10:11
  • 2
    try `hexdump -C your_file` instead. By default, `hexdump` prints two-byte unsigned values. – Sander De Dycker Mar 01 '16 at 10:14
  • Thanks a lot! The -C switch works and I have also modified the program to use unsigned short integers and now the output is the same as hexdump's. I see I have to do a little more research on the endian topic as it still confuses me. Thanks again for your hints! – Dirk Mar 01 '16 at 10:35

0 Answers0